Bug in MSVC?
-
Sorry, mir fiel kein besseres Topic ein...
Ich spiele gerade ein wenig mit MSVC 7.1, weil ich demnächst darauf umsteigen will / muß.
Dabei habe ich folgendes Phänomen:
#include "stdafx.h" #include <string> using namespace std; class xstring: public string { public: xstring(const char* c) { this->string::operator=(c); }; }; class cBase { public: cBase(): S1("ein"), // wenn man eine der beiden S2("Test") // Initialisierungen wegläßt, {}; // gibts 'nen Compiler-Fehler ?!? xstring S1; xstring S2; }; int _tmain(int argc, _TCHAR* argv[]) { cBase b1; cout << b1.S1.c_str() << endl; cout << b1.S2.c_str() << endl; return 0; }
In dieser Form wird es kompiliert. Wenn ich jedoch einen der beiden Parameter aus der Initialisierungsliste weglasse,
... public: cBase(): S2("Test") {}; ...
kommt diese Fehlermeldung:
*
error C2512: 'xstring' : no appropriate default constructor available
*Irgendwie finde ich da keine Logik drin. Ist das ein Bug in MSVC?
-
Ohne mir dein Problem genauer angesehen zu haben, kann ich dir eines sagen. Dies ist das falsche Forum. Direkt unter dem Forum "C++" gibt es das Forum "C# und .NET" dort gehört dein Thema auch hin.
Code-Hacker
-
Verrätst du mir noch, auf welche Zeile sich der Fehler bezieht?
mfG
-
Du hast xstring nunmal nur den einen Konstruktor gegeben (außerdem hat es automatisch einen Kopierkonstruktor). Ein leerer Standardkonstruktor wird nur generiert, wenn du keinen eigenen deklarierst. Hat nix mit VC7.1 zu tun, das sollte in VC6 wie in GCCsonstwas genau denselben Fehler geben. Konstruktoren werden in C++ nicht vererbt.
BTW ist es nicht nett, von std::string abzuleiten, weil die Klasse keinen virtuellen Destruktor hat. Wozu auch?
-
Code-Hacker schrieb:
Ohne mir dein Problem genauer angesehen zu haben, kann ich dir eines sagen. Dies ist das falsche Forum. Direkt unter dem Forum "C++" gibt es das Forum "C# und .NET" dort gehört dein Thema auch hin.
Unsinn.
-
@operator void:
Daran kanns IMHO nicht liegen, denn für jede Initialisierung muß der Konstruktor je einmal aufgerufen werden - das funktioniert ja auch. Nur: wenn ich eine der beiden Initialisierungen weglasse, kompiliert er das nicht mehr *grübel*
-
Is doch klar. Sobald du einen eigenen Konstruktor geschrieben hast, ist der Standard-Konstruktor nicht mehr verfügbar.
Eine Lösung wäre nun, den xstring-Konstruktor zu überladen und einfach
xstring () {};
zu schreiben.
Du kannst ja nich unter public: xstring S1("abc"); schreiben. Das gibt einen Fehler. Um deinen Konstruktor zu nutzen, schreibst du Public: xstring S1; und im andern Konstruktor S1("abc") .
MfG
-
@Saiyaman: Das isses eben nicht. Der Code wird kompiliert und läuft. Nur wenn ich eine oder beide Initialisierungen an der kommentierten Stelle weglasse, dann kompiliert er nicht. Und das versteh ich nicht
-
#include "stdafx.h" #include <string> using namespace std; class xstring: public string { public: xstring(const char* c) { this->string::operator=(c); }; xstring() {}; // <-- der muss jetzt rein ;) }; class cBase { public: cBase(): //S1("ein"), // wenn man eine der beiden S2("Test") // Initialisierungen wegläßt, {}; // gibts 'nen Compiler-Fehler ?!? xstring S1; xstring S2; }; int _tmain(int argc, _TCHAR* argv[]) { cBase b1; cout << b1.S1.c_str() << endl; cout << b1.S2.c_str() << endl; return 0; }
Kann mir nich vorstellen, dass das so nich funzt.
MfG
-
Lässt sich compilieren,
aber wieso von std::string erben ?
-
Genau. Man schreibt sich am besten ne ganz persönliche CString-Klasse selbst
MfG
-
std::string * t = new xstring; delete t; // hat std::string nen virtuellen destruktor ?
-
@Knuddelbaer: Hast Du jemals nen string so verwendet? Mit new angelegt? Ich nicht.
@CodeWalker: Es wurde doch jetzt schon mehrfach beschrieben, warum das so ist. Mit Deinen Initialisierungen rufst Du den von Dir zur Verfügung gestellten Konstruktor auf. -> alles klappt
Läßt Du die Initialisierung weg, dann denkt sich der Compiler: Gut, dann nehmen wir eben den Default-Konstruktor. Da Deine Klasse einen solchen aber nicht besitzt meldet er nen Fehler. Klar?
-
@ Jester: ah - jetzt - ja
Danke, ich stand wohl bißl auf dem Schlauch
-
Jester schrieb:
@Knuddelbaer: Hast Du jemals nen string so verwendet? Mit new angelegt? Ich nicht.
Pfffff... Du fragst mich sachen
Also die suche nach new string bzw. new std::string hat nichts ergeben in meinen Sources. Ich hab nu aber nicht die libs abgesucht die templateparameter erwarten ...
Ich hab mir std::string als noch nich angeschaut ob es da nen virtuellen Destruktor gibt. Wenn es den nicht gibt ist die Klasse afaik nicht fürs ableiten gedacht. Und ein Kommentar bringt Dir bei einem crash auch nichts.
(Theorie (heile Welt) und praxis (wirtschaftlichkeit) sind 2 getrennte Themen ;o)
-
Knuddlbaer schrieb:
Ich hab mir std::string als noch nich angeschaut ob es da nen virtuellen Destruktor gibt. Wenn es den nicht gibt ist die Klasse afaik nicht fürs ableiten gedacht. Und ein Kommentar bringt Dir bei einem crash auch nichts.
Natürlich hat string keinen virtual dtor - wäre ja nur ne performance bremse.
Und wer verwendet einen value type denn schon polymorph?
Aber die Frage ist wohl eher: was bringt die Ableitung in diesem Fall?
-
Jetzt nur noch die ; nach den Konstruktoren löschen - die gehören da nicht hin