Informatiker Board (http://www.informatikerboard.de/board/index.php)
- Themengebiete (http://www.informatikerboard.de/board/board.php?boardid=1)
--- Praktische Informatik (http://www.informatikerboard.de/board/board.php?boardid=6)
---- Softwaretechnik (http://www.informatikerboard.de/board/board.php?boardid=18)
----- Copy Constructor C++ (http://www.informatikerboard.de/board/thread.php?threadid=2653)


Geschrieben von Tommy am 02.12.2015 um 16:08:

  Copy Constructor C++

Ich habe eine kleine Unklarheit beim Erstellen eines Copy Constructors, der eine tiefe Kopie erzeugen soll:

code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:

CMatrix::CMatrix(int M, int N)
{
	m_rows=M;
	m_cols=N;
	m_size=m_rows*m_cols;
	m_pArray = new double[m_size];
}

CMatrix::CMatrix(const CMatrix& orig)
{

//	double* m_pArray;                             
//	m_pArray = new double[orig.m_size];   

	m_pArray = orig.m_pArray;
	m_rows = orig.m_rows;
	m_cols = orig.m_cols;
	m_size = orig.m_size;


	for (int i=0; i<m_size; i++)
		{
			m_pArray[i] = orig.m_pArray[i];
		}

		return;

}


Ich war der festen Überzeugung, dass ich erst wie im auskommentierten Teil ein neues dynamische Array erzeugen muss, mit den Variablen von dem Array das ich kopieren möchte.
Allerdings stürzt das Programm dann immer ab.

Ohne den auskommentierten Teil funktioniert das Ganze wunderbar, ich habe in meiner printfunktion mittles "this" und "&m_pArray" die Adressen der beiden Objekte und deren Arrays überprüft und festgestellt, dass sie unterschiedliche Adressen haben.

Daher gehe ich davon aus, dass die Inhalte auch in unterschiedlichen Adressen gespeichert sind, wie in einer tiefen Kopie vorgesehen.

Aber wieso?

Ich habe doch gar kein neues Array erzeugt ?

Oder ist das der Teil, der ein neues dynamisches Array erzeugt?

code:
1:
2:
3:
4:
5:
        m_pArray = orig.m_pArray;
	m_rows = orig.m_rows;
	m_cols = orig.m_cols;
	m_size = orig.m_size;


Und wenn ja, wieso muss ich dann nicht "new" benutzen ?

Liegt das daran, dass die Zeile " m_pArray = orig.m_pArray " auf die Zeile im Default Konstruktor verweist und für den Compiler so aussieht: "m_pArray = new double[m_size]" ?
Also, dass quasi der Teil hinter dem Gleichheitszeichen durch den Teil im Default Konstruktor ersetzt wird ?

Und da die Variable "m_pArray" in meiner Klassendefinition schon intitalisiert wurde, muss ich das nicht ein zweites Mal machen ?

Ich hab das Gefühl ich steh vorm Baum und seh den Wald nicht verwirrt



Geschrieben von Karlito am 05.12.2015 um 11:38:

 

Hallo Tommy,

das Problem ist, dass Du in Zeile 13 m_parray neu definierst. Du musst die Klassenvariable weiter verwenden. Weiterhin ist Zeile 16:
code:
1:
2:
3:
m_pArray = orig.m_pArray;


flasch, da Du damit den alten Pointer auf das Array auf die neue Klassenvariable kopierst.

Schau dir mal folgenden Code an:
code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
CMatrix::CMatrix(int M, int N)
{
	m_rows=M;
	m_cols=N;
	m_size=m_rows*m_cols;
	m_pArray = new double[m_size];
}

CMatrix::CMatrix(const CMatrix& orig)
{

	//	double* m_pArray;                             
	m_pArray = new double[orig.m_size];   

	//m_pArray = orig.m_pArray;
	m_rows = orig.m_rows;
	m_cols = orig.m_cols;
	m_size = orig.m_size;


	for (int i=0; i<m_size; i++)
	{
		m_pArray[i] = orig.m_pArray[i];
	}

}


Gruß,

Karlito


Forensoftware: Burning Board, entwickelt von WoltLab GmbH