Copy Constructor vs Copy Assignment Operator

Intrebari despre limbajul C++, standardul C++, STL, OOP in C++ sau alte subiecte nelegate de VisualC++
Post Reply
garzanti
Junior
Junior
Posts: 10
Joined: 20 Jan 2010, 17:19
Judet: Iaşi

Copy Constructor vs Copy Assignment Operator

Post by garzanti » 03 Apr 2013, 14:30

In secventa de cod de mai jos copy assignment operator-ul nu este apelat niciodata, practic compilatorul il inlocuieste cu un apel catre copy constructor. Care este motivul din spatele acestei decizii?

Code: Select all

class AClass {
public:
	AClass();
	AClass(const AClass& x);

	AClass& operator =(const AClass& x);

	int z;
};

int main(void) {
	
	AClass a;
	a.z = 6;

	AClass b = a;

	printf("%d\n", b.z);

	AClass c = b;
	return 0;
}

AClass::AClass()
{
	printf("AClass ctor\n");
}

AClass::AClass(const AClass& x)
{
	z = x.z;
	printf("AClass copy ctor\n");
}

AClass& AClass::operator =(const AClass& x)
{
	printf("AClass assignment operator\n");
	return *this;
}



Viorel
Microsoft MVP
Microsoft MVP
Posts: 293
Joined: 13 Jul 2007, 12:26

Re: Copy Constructor vs Copy Assignment Operator

Post by Viorel » 03 Apr 2013, 14:55

Acest exemplu denotă faptul că expresia ”AClass b = a” semnifică o construcție de inițializare care este echivalentă cu ”AClass b(a)”. Deci aici nu este implicat operatorul ”=”. Pentru a interzice aceste construcții se poate folosi cuvîntul explicit:

Code: Select all

explicit AClass( const AClass & x);
Acum în loc de ”AClass b = a” (care nici nu se compilează) se va scrie ”AClass b; b = a” (care apelează operatorul ”=”) sau ”AClass b(a)” (care apelează constructorul de copiere).

User avatar
Marius Bancila
Fondator
Fondator
Posts: 2344
Joined: 11 Jul 2007, 11:45
Judet: Timiş
Location: Timisoara
Contact:

Re: Copy Constructor vs Copy Assignment Operator

Post by Marius Bancila » 03 Apr 2013, 17:21

Pai alternatica ar fi ca construiasca obiectul c, apoi sa copieze pe b in c. Asta inseamna o operatie in plus, fata de construirea directa a lui c prin copiere din b. Copy constructor = default constructor + copy assignment operator. Deci salvezi o operatie.
Marius Bancila
Fondator Codexpert, Microsoft MVP VC++
Site personal | Blog

User avatar
bu7ch3r
Membru++
Membru++
Posts: 326
Joined: 17 May 2011, 15:17
Judet: Iaşi
Location: Sofia
Contact:

Re: Copy Constructor vs Copy Assignment Operator

Post by bu7ch3r » 03 Apr 2013, 17:28

Ia pune tu inainte de return0 : c = b; asa simplu :)
Cu stima,
Lupu Claudiu

garzanti
Junior
Junior
Posts: 10
Joined: 20 Jan 2010, 17:19
Judet: Iaşi

Re: Copy Constructor vs Copy Assignment Operator

Post by garzanti » 04 Apr 2013, 16:23

"A common source of confusion with new C++ programmers is assignment." Bruce Eckel, Thinking in C++ vol. 1, pag. 548. Eu nu am multa experienta, dar am observat colegi cu multa experienta carora nu le era clar. Conform ISO 2011 o sintaxa de genul:

Code: Select all

AClass b = a;
se cheama copy-initialization (8.5 Initializers, 14), iar initializarea se face folosind copy-constructor. Nu am gasit in ISO o explicatie pt alegerea asta, insa o explicatie gasita pe net ar fi: Even though there's an "=" there, that's just a syntax holdover from C... this is always initialisation, never assignment, and so operator= is never called.

Asa cum a spus Marius daca cineva doreste sa evite copy-initialization poate rescrie linia anterioara:

Code: Select all

AClass b;
b = a;

User avatar
Ovidiu Cucu
Fondator
Fondator
Posts: 3778
Joined: 11 Jul 2007, 16:10
Judet: Iaşi
Location: Iasi
Contact:

Re: Copy Constructor vs Copy Assignment Operator

Post by Ovidiu Cucu » 04 Apr 2013, 20:05

Mai pe scurt:
Pentru...

Code: Select all

AClass b = a; 
...se apeleaza un constructor, atat si nimic mai mult (constructorul de copiere daca a este de tipul AClass). Punct si de la capat.
Asta e sintaxa in C++, cu asta defilam. ;)
Sau se mai poate spune ca in linia de mai sus se face o initializare si nu o atribuire.

User avatar
Marius Bancila
Fondator
Fondator
Posts: 2344
Joined: 11 Jul 2007, 11:45
Judet: Timiş
Location: Timisoara
Contact:

Re: Copy Constructor vs Copy Assignment Operator

Post by Marius Bancila » 05 Apr 2013, 09:40

Asa cum a spus Marius daca cineva doreste sa evite copy-initialization poate rescrie linia anterioara:
Eu n-am spus asta. Asta e reciproca a ceea ce am spus. Am spus ca idea contructorului de copiere e sa evite construirea urmata de copiere, pentru ca inseamna operatii in plus. Nu inteleg de ce cineva ar vrea sa evite aceasta optimizare. Poate ne dai un exemplu.
Marius Bancila
Fondator Codexpert, Microsoft MVP VC++
Site personal | Blog

Post Reply