Grundlegender C++ Fehler - Konvertierung nicht möglich
-
Saul schrieb:
bin gerade dabei mich ein wenig in C++ einzuarbeiten...
Und stolperst dabei schon über sehr viele Fehler.
1. Das ist kein C++, sondern C++/CLI (was eine eigene Sprache mit einem eigenen Unterforum ist). Den Ausdruck "ref class" gibt es im ANSI C++ nicht.
2. Ich mag mich irren, aber Typen wie int werden soviel ich mich nicht irre in C++/CLI genauso wie in C++ und C# als Wert [Kopie], nicht als Referenz übergeben (Bei ANSI C++ gilt dies für alle Typen), und eine Änderung eines solchen Übergabeparameters, ändert daher nur die Kopie, nicht den Ursprungswert.
3. Wenn der Übergabeparameter genauso wie die Membervariable lautet, musst du genauer angeben, was gemeint ist (in C++ z.B. "this->a = a;"), die am lokalsten deklarierte Variable (hier der Übergabeparameter) hat immer Vorrang.
...
-
trooper schrieb:
Warum #pragma once
Das ist ein MSVC-Ersatz für Include-guards. Kann man auch gleich weglassen und durch richtige include-guards ersetzen, da es sonst sowieso nicht portabel ist.
-
Das pragma kenne ich nur es ist schlicht nicht nötig
(weil nicht portabel, wie du bereits sagtest)
-
pumuckl schrieb:
- ich weiß nicht was das "ref" vor "class Sum" soll, es ist auf jeden Fall kein gültiges Standard-C++
Es bezeichnet einen managed type in C++/CLI. Siehe http://msdn.microsoft.com/de-de/library/ms235220.aspx
-
Michael E. schrieb:
pumuckl schrieb:
- ich weiß nicht was das "ref" vor "class Sum" soll, es ist auf jeden Fall kein gültiges Standard-C++
Es bezeichnet einen managed type in C++/CLI. Siehe http://msdn.microsoft.com/de-de/library/ms235220.aspx
Na dann verschieb ich das Ganze mal ins entsprechende Forum, in der Hoffnung dass das Verhalten ein CLI-"Feature" ist, das dort erklärt werden kann? (z.B. kein automatisch generierter Copy-Ctor? das könnte es erklären)
-
Dieser Thread wurde von Moderator/in pumuckl aus dem Forum C++ in das Forum C++/CLI mit .NET verschoben.
Im Zweifelsfall bitte auch folgende Hinweise beachten:
C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?Dieses Posting wurde automatisch erzeugt.
-
Ups, da hab ich ja ne mächtige Resonanz erhalten ...
War mir zwar bewusst das es C++/CLI ist, aber ich dachte man kann Ansi C++ einfach in das Projekt übernehmen ... Ich hatte nicht vor damit zu verwirren und ja es ist genau der Originalcode.
Den Destruktor hatte ich ersteinmal nur so für mich mit reingeschrieben, wenn ich es richtig verstanden habe muss ich später durch delete die Instanzvariablen freigeben? Oder gehört da noch mehr dazu?asc schrieb:
2. Ich mag mich irren, aber Typen wie int werden soviel ich mich nicht irre in C++/CLI genauso wie in C++ und C# als Wert [Kopie], nicht als Referenz übergeben (Bei ANSI C++ gilt dies für alle Typen), und eine Änderung eines solchen Übergabeparameters, ändert daher nur die Kopie, nicht den Ursprungswert.
War das jetzt auf die Methode addieren oder auf getParams bezogen?
pumuckl schrieb:
Das ist ein MSVC-Ersatz für Include-guards. Kann man auch gleich weglassen und durch richtige include-guards ersetzen, da es sonst sowieso nicht portabel ist.
Verstehe ich nicht ganz? Welche includes müsste ich dafür nehmen?
Wenn ich den Code von Trooper übernehme, erhalte ich trotzdem noch die von mir erwähnte Fehlermeldung
-
Interessant, denn bei mir läuft der Code unter GCC und MSVC.
Hast du das Programm genau so übernommen oder in deinen Code reinkopiert?
Welchen Compiler nutzt Du denn?
Mit welchen Parametern rufst Du den Compiler auf?PS:
includes brauchst Du dafür gar keine:Eine .h-Datei wird so umschlossen:
#ifndef _HEADERNAME_H_ #define _HEADERNAME_H_ #endif
-
Saul schrieb:
War mir zwar bewusst das es C++/CLI ist, aber ich dachte man kann Ansi C++ einfach in das Projekt übernehmen ...
Dein Code war aber kein Ansi C++ - daher liegt die Problematik auch kaum an der Übernahme von Ansi C++. Das Schlüsselwort "ref" aus C++/CLI macht sehr viel aus.
Saul schrieb:
...wenn ich es richtig verstanden habe muss ich später durch delete die Instanzvariablen freigeben? Oder gehört da noch mehr dazu?
In Ansi C++ muss man genau dann eine Variable per delete Freigeben, wenn diese per new allokiert wurde. Managed Klassen werden in C++/CLI per Garbage Collector freigegeben.
Und ich glaube auch das du Managed-Klassen mit gcnew (oder so ähnlich) allokieren musst, und du hierbei keine Stackvariablen einsetzen kannst.
Sum Summe1, Summe2;
Diese Zeile bedeutet was ganz anderes mit einer unmanaged (class) oder einer managed (ref class) Klasse. Bei ersteren erzeugst du hier Stackvariablen, bei letzeren nur (ich kenne C++/CLI nur am Rande, daher kann ich mich irren) managed Referenzen, wo du die Erzeugung explizit mit gcnew durchführen musst.
-
Also ich hatte meinen Code abgeändert.
Es lag an dem ref ... wenn ich es lösche übersetzt er es auch. Das ref wurde aber erzeugt, als Visual Studio die Klasse erstellt hat. Genau wie das #pragma once. Das hatte auch Visual Studio mit reingeschrieben.
Wozu dienen denn diese beiden Einträge eigentlich?
-
Saul schrieb:
...ref...#pragma once...
Wozu dienen denn diese beiden Einträge eigentlich?Das wurde bereits im Thread erwähnt, hier aber nochmals:
Diese spezielle Pragmadirektive ist eine Compilerspezifische (wenn auch durchaus bei mehreren Compilern verwendete) Abkürzung der klassischen Includeguards.
Das ref deklariert eine Klasse als managed-Datentyp (was unter C++/CLI der Standard wäre, und somit auch logisch, das dies automatisch hinzugefügt wurde). Und den unterschied zwischen managed und unmanaged Datentypen solltest du selbst wissen, wenn du mit C++/CLI arbeitest.
-
Ok danke nochmal für den Hinweis.
Habt mir sehr geholfen!!
Gruß Saul
-
asc schrieb:
und du hierbei keine Stackvariablen einsetzen kannst.
Das stimmt nicht, in C++/CLI gibt es Stacksemantik, sonst würde man z.B. kein RAII machen können.
Allerdings ist das alles "Compiler Magic", weil CLR-Objekte nur auf dem managed Heap existieren können.
Saul schrieb:
Wozu dienen denn diese beiden Einträge eigentlich?
Du hast in Visual Studio den falschen Projekttyp angelegt.
C++/CLI ist eine Sprache die dazu dient, die native C++ Welt und die .net Welt miteinander zu verbinden. Deshalb gibt es dort C++ Objekte (class) und .net Objekte (value class, ref class).
D.h auch jetzt machst du kein richtiges Windows C++ Programm, sondern übersetzt C++ in ein .net Programm.
-
nn schrieb:
Du hast in Visual Studio den falschen Projekttyp angelegt.
C++/CLI ist eine Sprache die dazu dient, die native C++ Welt und die .net Welt miteinander zu verbinden. Deshalb gibt es dort C++ Objekte (class) und .net Objekte (value class, ref class).
D.h auch jetzt machst du kein richtiges Windows C++ Programm, sondern übersetzt C++ in ein .net Programm.
Naja also ich benötige eigentlich eine Windows Forms-Anwendung und das scheint ja nur über .Net möglich zu sein oder irre ich mich da?
Vielleicht bin ich auch einfach nur im falschen Foren-Abschnitt gelandet?
-
Saul schrieb:
Naja also ich benötige eigentlich eine Windows Forms-Anwendung
Warum in C++/CLI ? Das geht in C# viel besser.
Selbst, wenn man da ANSI-C++ Code einbinden will, besser daraus eine DLL machen mit exportierten C-Funktionen oder C++/CLI-Klassen und im C#-Projekt als Verweis hinzufügen.
-
Kann mir die Variante mit C# ja später nochmal anschauen. Werd aber erstmal so weitermachen...
Hab da nochmal ne generelle Frage. Wieso gibt er mir eine Fehlermeldung aus, wenn ich die Initialisierung mit Initialisierungskonstruktor realisieren möchte?
Sum Summe1, Summe2 = Sum(10,10); Summe1.setParams(10,20); //Summe2.setParams(10,10); Summe1.addieren(Summe2);
bzw.
Sum Summe1, Summe2(10,10);
Keine Überladene Funktion akzeptiert 2 Argumente
Normal müsste das doch gehen
-
Sum Summe1, Summe2(10,10);
Dafür benötigst du zunächst einmal einen Konstruktor der die beiden Werte entgegenimmt.
Summe(int a, int b) { }
Dann hast Du aber das Problem, dass der erste Konstruktor nicht aufgerufen werden kann, da der so wäre
Summe(void) { }
Nun kannst du beide implementieren...
Sum(void) { a=0; b=0; } Sum(int a, int b) { this->a = a; this->b = b; }
... was funktionieren würde.
Oder du machst es gleich mit Default-Werten:
Sum(int a=0, int b=0) { this->a=a; this->b=b; }
Hier geht ein Konstruktor für beides.
Ich hoffe das hilft Dir weiter.
-
Ahhhh ok, ich verstehe ...
Danke dir trooper