Werte einer Klasse einer neuen Klasse zuweisen



  • Hallo,
    ich habe eine Klasse erstellt, in der ich verschiedene Variablen abspeichern kann:

    class CTest
    {
    public:
    	double			min,max;
    	CString			str;
    	CList<double,double&>	Data;
    }
    

    Im Programm erstelle ich dann ein Objekt und weise einen Wert zu:

    CTest X;
    X.min=1.234;
    

    In meinem Programm habe ich nun mehrere Instanzen (?) von der Klasse CTest erstellt. Nun möchte ich in etwa folgendes machen:

    CTest Y;
    Y=X;
    

    Dann sollte Y.min=1.234 sein. Geht das irgendwie ? Oder muss ich da irgendwein Konstruktor schreiben, der die Werte manuell zuweist ?



  • Du brauchst einen operator= in dem Atemzug kannst du gleich einen Copy-Konstruktor machen, der ist dann ein Einzeiler. 🙂

    Auch andere Operatoren musst du selber machen. == != < > ++ usw.



  • hm,
    und wie geht das ? ich würd halt dort irgendwie ne funktion schreiben, die die werte manuell zuweist. meinst du das mit copy konstruktor ?



  • Das sind C++ Grundlagen... 🙄

    Hast du ein Buch dazu? Ich müßte so eines sonst abschreiben.
    Wenn du magst, schaue ich mal nach, in welchem von meinen das so nett erklärt war.

    Copy-Konstruktor ist die Funktion, die bei sowas aufgerufen wird:

    CTest Y(X);
    

    Das tut ja so fast das gleiche. 🙂



  • Das meinte ich,
    im Konstruktor die Werte des übergebenen Objekts dem zu erzeugendem Objekt zuweisen. Sowas nennt man wohl Copy-Konstruktor... Hab schon länger kein C++ Grundlagenbuch mehr gelesen.

    CTEST::CTEST(CTEST &ptr)
    {
    min=prt.min;
    max=prt.max;
    }
    //oder so ähnlich
    

    Ich hab halt gedacht, sowas kann man auch irgendwie "automatischer" machen. Aber egal, funzt ja auch so.



  • Nein, automatisch geht das nicht, nur halbautomatisch. Ich glaube (!), dss du jetzt auch mit Zuweisungen arbeiten kannst, weil der automatisch den Copy-Konstruktor nimmt.

    Ich lese auch nicht dauernd solche Bücher, ich weiß nur, dass ich sowas schon mal gelesen habe - finde nur das Buch grade nicht. 😞



  • Hi,

    es geht schon automatisch, wenn du einfache Datentypen hast. z.B. long, float
    double, char oder Zeiger. Doch vorsicht bei Zeigern! Es werden immer die
    Adressen kopiert. D.h. wenn Du in einer Klasse einen Zeiger auf char* hast
    und die Klasse kopierst, kopierst Du in der neuen Klasse die Adresse der
    zu kopierenden Klasse. Das wiederum heist, wenn die Kopierte Klasse zerstört
    wird, enthält die Kopie einen Zeiger auf ungültigen Speicher!

    Deswegen muss man zwei Operatoren Überladen.

    1. den Copy-Konstruktor
    2. den Zuweisungskonstruktor

    Wenn Deine Klasse die CList nicht enthalten würde, würde also alles automatisch
    gehen, weil der Kompiler die beiden Operatoren automatisch erzeugt.

    Jetzt zu Deiner Klasse.

    Wegen der CList must du also einen Copy-Konstruktor und einen Zuweisungsoperator
    schreiben.

    Das sieht dann so aus:

    class CTest
    {
    public:
    	double min, max;
    	CString str;
    	CList<double, double> data;
    	CTest() {}; // Default Constructor
    	CTest(const CTest& rh) // Copy-Constructor 
    	{
    		*this = rh; // kann auch Zuweisung aufrufen und spart dadurch doppelten Code!
    	}
    
    	CTest& operator = (const CTest& rh) // Assignement
    	{
    		if ( this == &rh )
    			return *this; // schutz vor Selbstzuweisung!
    
    		this->max = rh.max; // copy
    		this->min = rh.min; // copy
    		this->str = rh.str; // copy
    		this->data.RemoveAll(); // clear array (neue Zuweisung)
    		this->data.AddHead(const_cast<CList<double, double>* >(&rh.data)); // special copy!
    
    		return *this; 
    	};
    };
    

    OK, das wars auch schon.... Hexenwerk?

    Nun ist also folgendes möglich:

    int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
    {
    	int nRetCode = 0;
    
    	// initialize MFC and print and error on failure
    	if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
    	{
    		// TODO: change error code to suit your needs
    		_tprintf(_T("Fatal Error: MFC initialization failed\n"));
    		nRetCode = 1;
    	}
    	else
    	{
    		// TODO: code your application's behavior here.
    	}
    
    	CTest x; // Instanz erzeugen
    	x.max = 100;
    	x.min = 10;
    	x.str = _T("Test");
    	x.data.AddTail(5.0);
    	x.data.AddTail(7.0);
    	x.data.AddTail(9.0);
    	x.data.AddTail(3.0);
    
    	CTest y(x); // Copy-Instanz erzeugen
    
    	CTest xy = y; // Assignment-Instanz erzeugen
    
    	return nRetCode;
    }
    

    Im Debugger siehst Du nun, das alle Werte kopiert wurden und nicht einfach
    Referenziert mit ausnahme des CString-Members, das liegt daran, weil CStrings
    Referenz gezählt werden.

    Referenzgezählte Objekte sind eine Thema für sich, aber der Rest sollte nun
    klar sein.

    Gruss
    EB


Anmelden zum Antworten