Fehler bei CString-Rückgabe
-
dlgig schrieb:
Habe jetzt den Rückgabewert auf CString geändert. Jetzt gehts.
ABER ich dachte, dass voneinander abgeleitete Klassen zueinnader Kompatibel sind.Nein, nicht zueinander. Ein
Derivedist sicher einBaseund kann als solches angesehen werden (sofernpublic-Vererbung eingesetzt wurde). Umgekehrt ist einBase-Objekt keinDerived.Moi schrieb:
Der ganze Laufzeitpolymorphiekram funzt nur mit Pointern.
Mit Referenzen geht es auch. Hier muss man vorsichtig sein: Verweise (Zeiger/Referenzen) auf abgeleitete Klassen können implizit als solche auf Basisklassen angesehen werden. In umgekehrter Richtung muss man entweder
dynamic_casteinsetzen, um eine Laufzeitprüfung zu erhalten, oderstatic_cast, das aber bei fehlerhaftem Downcast undefiniertes Verhalten hervorruft.
-
Danke.
Jetzt gehts auch so.Habe jetzt wie Moi gesagt, den fehlenden Konstruktor hinzugefügt
CPPString::CPPString(CString csString):CString(csString) // Notwendig für Typcasting: CString To CPPString { m_strString = (char*)calloc(0,sizeof(char)); }Denke ich habe auch den Grund verstanden:
Immer wenn ein TypeCast notwendig ist: Basisklasse in AbgeleiteteKlasse
dann ist ein Konstruktor erforderlich, denn
bei jedem TypeCast wird der Konstruktor aufgerufen.Richtig?
-
m_strString = (char*)calloc(0,sizeof(char));das sieht extrem falsch aus...
-
Hm... naja.
Ich würde lieber dendynamic_castbevorzugen, denn genau dafür ist er da.> bei jedem TypeCast wird der Konstruktor aufgerufen.
Kann man nicht allgemein sagen. Der Compiler sucht verschiedene Möglichkeiten, wie er casten kann. Irgendwann kommt er auf die Konstruktoren. Wenn das Objekt, das gecastet werden soll, als Parameter im Konstruktor vorhanden ist, wird der Compiler versuchen, diesen Konstruktor zu benutzen.
class HoldsAnInt { private: int data; public: HoldsAnInt(int d) : data(d) { } }; void f(HoldsAnInt hai); [ ... ] f(23); // == f(HoldsAnInt(23)) (Funktionsartiger Cast) == f(static_cast<HoldsAnInt>(23))Das kann man natürlich auch mit abgeleiteten Klassen, dynamischer Polymorphie und Heap-Objekten machen machen. Entweder macht der Compiler die Arbeit des Castens zu seiner Zeit (per explizitem Konstruktor) oder das Programm selbst zur Laufzeit (mit Offsets).
-
Hat eigtl schon mal jmd gesagt, dass man das, was du dort machst, nicht machen sollte?

Was spricht gegen eine freie Funktion?
Den Aufbau deiner Klasse versteh ich eh nicht ganz... wofür nochmal der pointer? cstring hält doch den string an sich schon!?
-
unskilled schrieb:
m_strString = (char*)calloc(0,sizeof(char));das sieht extrem falsch aus...
Warum das? Ich allokiere erstmal 0 Byte Speicher.
Später wird er dynamisch mit realloc angepasst.
Ich allokier gleich am anfang irgendwas, damit ich später nicht mehr unterscheiden muss, ob der zeiger noch null ist oder schon auf speicher verweist.
-

-
unskilled schrieb:
Hat eigtl schon mal jmd gesagt, dass man das, was du dort machst, nicht machen sollte?

Bin mir nicht ganz sicher, ob du mich meints.
[quote]Was spricht gegen eine freie Funktion?
Den Aufbau deiner Klasse versteh ich eh nicht ganz... wofür nochmal der pointer? cstring hält doch den string an sich schon!?Ich wollte eine Funktion integrieren, die mir den CString als Char-Array ausgibt.
Manchmal ist man ja auf char* angewiesen z.B. wenn man mal sprintf, fopen, _popen().
Da die guten alten C-Funktion manchmal doch besser zu handeln sind oder man ein Char-Array viel besser durchparsen kann.@Ad aCTa
Verstehe dein Beispiel nicht ganz. Was macht der Code?
-
Ich wollte eine Funktion integrieren, die mir den CString als Char-Array ausgibt.
Gibts schon: GetBuffer()
http://msdn.microsoft.com/en-us/library/5bzxfsea.aspx
Simon
-
[quote="theta"]
Gibts schon: GetBuffer()
http://msdn.microsoft.com/en-us/library/5bzxfsea.aspx
SimonGeht leider nicht bei Unicode-Unterstützung. Also wenn dort der Haken gesetzt für Unicode-Libories gesetzt ist, gehts damit nicht mehr - bekomme so nur das 1. Zeichen.
Deswegen mache ich das so:
char* CPPString::GetCharArray(void) { int iLenght = (*this).GetLength(); m_strString = (char*)realloc( m_strString, sizeof(char)*(iLenght+1) ); int i = 0; for ( i=0; i<iLenght; i++ ) { m_strString[i] = (char)(((LPCTSTR)(*this))[i]); } m_strString[i] = '\0'; return m_strString; }
-

-
Geht leider nicht bei Unicode-Unterstützung.
Das würd ich bezweifeln wollen... was heißt denn geht nicht? minimalbsp?
(am besten so was, wie#include <iostream> #include <CString> //richtig? int main() { CString test = L"asd"; std::wcout << test.GetBuffer() << std::endl; }. ich hab nur kein von der cli(?)-bibliothek - aber ich denke ja, du castest irgendwo nach char* und das war der fehler...)
sry, aber das was du hier machst, ist alles iwie total falsch und hässlich und noch viel mehr... du solltest dich noch ein wenig belesen, bevor du das nächste mal so etwas versuchst ;o)
ich würde solche fkt auch prinzipiell als freie fkt. implementieren, fänd ich auch viel zweckmäßiger...
thetas quellcode hatte nur am rande was mit deinem problem zu tun ;o) sein quelltext hat in so fern keinen bezug zu deinem eigentlichen problem (da gings um dynamic_cast und dessen funktionsweise)
bb
-
ich hab nur kein von der cli(?)-bibliothek
ehm, was mit cli? CString kommt aus der MFC / ATL, reines C++, ausgeschmückt mit unmengen von Makros...
Oder hab ich was verpasst?Simon
-
theta:
Nö, das Fragezeichen sollte heißen, dass ich nicht weiß, ob das richtig ist... Hab noch nie mit der MFC gearbeitet... Wieso auch? ;Pbb
-
@unskilled: weil man masochistisch veranlagt ist?
-
Offtopic: Mault nicht so über die MFC rum. Sie ist a) immernoch angenehmer als die pure WinAPI und b) älter als der C++ Standard, das erklärt auch, warum sie so hässlich ist, keine Templates/Namespaces hat und so altmodisch aussieht. Sie ist einfach alt. Aber mächtig.
-
Was nimmt ihr den, wenn ihr C++ programmiert? Ich möchte eigentlich für kleine Programme kein riesen Framework verwenden.
Ich habe nie den Sinn von .Net verstanden (läuft doch sowieso nur unter Windowssystemen ordentlich) und bis jetzt konnte mir das keiner erklären.
Wozu auf jeden PC nen fettes Framework vorraussetzten, wenn es doch leistungsstarke Compiler gibt?
Ich mag die MFC auch nicht, aber womit kann man sonst in C++ GUI-Anwendungen schreiben?
Ich kenne nur LabWindows CVI, was aber reines ANSI C ist, doch nirgendwo lassen sich oberflächen so einfach und bequem gestalten als damit.
MFC ist ein Graus. Es gibt noch nichtmal ein Control, mit dem ich Zahlen eingeben lassen kann (wo rechts daneben noch Hoch-Runter-Pfeile sind etc.
-
Hallo dlgig,
s. http://msdn.microsoft.com/en-us/library/c8z1ck76%28VS.80%29.aspx. Einfach mit SetBuddy an ein anderes Control (z.B. CEdit) hängen.Aber ich bin auch kein Freund der MFC.
Um in C++ GUI-Anwendungen zu schreiben, gibt es genügend andere Frameworks (QT, wxWidgets, GTK+), s.a. http://www.c-plusplus.net/forum/viewtopic-var-t-is-230583.htmlUm gute GUI-Programme zu entwickeln, kann ich jedoch C# mit dem .NET-Framework nur empfehlen (das .NET-Framework kann man auf heutigen Windows-Systemen genauso voraussetzen wie z.B. DirectX).