Overview
When using Class object, a copy constructor is used in the following three cases where the contents of one object are the initial value of another class object:
- Defines a class object and initializes it;
- Class object is passed as a parameter to the function;
- Class object as the return value of the function;
If the user does not display a declaration or define a copy constructor, C + + declares or defines an implicit copy constructor for class if necessary , and the copy constructor is trivial if the following conditions occur:
- Their class has no virtual functions and no virtual base class (es).
- All the direct base classes and non-static data members of the their class have trivial constructors.
- Otherwise, the copy constructor is non-trivial. implicitly-declared non-trivial copy constructor.
Default copy constructor
In the following four cases, the compiler synthesizes a non-trivial default copy constructor:
- When class contains a member object with copy constructor;
- When class inherits from a base class with copy constructor;
- When class declares that there is virtual functions;
- When class derives from virtual base class (es);
In the first two cases, the compiler must place the copy constructor of the member or base class in the default copy constructor, and the following example satisfies both cases:
#include <iostream>usingnamespacestd;class Foo {public: Foo() {} Foo(constcout"Foo‘s copy construct!" << endl; }};classpublic Foo {public: int x; Foo foo;};int main(){ Word ba; Word bb = ba; return0;}
Execution result: The compiler invokes a two-time copy constructor of the Foo class in the synthesized copy constructor;
(GDB) rstarting program:./test02 Breakpoint1, Main () atTest02.cpp: - -Word Ba; (gdb) Sword::word (this=0xbffff020) atTest02.cpp: One One classWord:public Foo {(gdb) Sfoo::foo (this=0xbffff020) atTest02.cpp:77Foo () {} (GDB) Sfoo::foo (this=0xbffff024) atTest02.cpp:77Foo () {} (GDB) Smain () atTest02.cpp: + +Word bb = ba; (gdb) Sword::word (this=0xbffff028) atTest02.cpp: One One classWord:public Foo {(gdb) Sfoo::foo (this=0xbffff028, foo= ...) atTest02.cpp:88Foo (const foo &foo) {cout <<"Foo ' s copy construct!"<< Endl; } (GDB) Sfoo ' sCopyconstruct! Foo::foo (this=0xbffff02c, foo= ...) atTest02.cpp:88Foo (const foo &foo) {cout <<"Foo ' s copy construct!"<< Endl; } (GDB) Sfoo ' sCopyConstruct!main () atTest02.cpp: A A return 0;(gdb) s at} (GDB)
In the third case, if an object of the same class is initialized directly, it can be done by bitwise copy, because vptr points to the same virtual function table, and if the base class object is initialized with a derived class object, the compiler will reset the class O Bject pointer to virtual table, because different classes of Vptr point to their own virtual function table;
#include <iostream>using namespace STD;classFoo { Public:Virtual voidFunc () {cout<<"virtual function in Foo!"<< Endl; }};classWord: PublicFoo { Public:voidFunc () {cout<<"virtual function in word!"<< Endl; }};intMain () {Word B1; Word B2 = B1;//Initialize between objects of the same class, Vptr direct copy, point to the same virtual function tableB2.func (); Foo foo = B1;//initialization between different classes of objects, cutting occurs, vptr not directly copied, pointing to different virtual function tableFoo.func ();return 0;}
Execution Result:
(GDB) b +Breakpoint1At0x8048809: File test03. cpp, line.(GDB) rstarting Program:/home/nifengweijifen/linuxstudy/objectmodel/chap02/test03 Breakpoint1, Main () at test03. cpp: + +Word B1;(GDB) sWord:: Word (this=0xbffff024) at test03. cpp: A AClass Word:public Foo {(GDB) sFoo:: Foo (this=0xbffff024) at test03. cpp:66Class Foo {(GDB) Smain () at test03. cpp: - -Word B2 = B1; Initialize between the same classes, copy the vptr directly, point to the same virtual function table(GDB) sWord:: Word (this=0xbffff028) at test03. cpp: A AClass Word:public Foo {(GDB) sFoo:: Foo (this=0xbffff028) at test03. cpp:66Class Foo {(GDB) Smain () at test03. cpp: + +B2. Func();(GDB) sWord:: Func (this=0xbffff028) at test03. cpp: the the{cout <<"virtual function in bar!"<< Endl; }(GDB) svirtual functioninchWord!main () at test03. cpp: at atFoo foo = B1; Initialization between different classes, cutting occurs, vptr not directly copied, pointing to different virtual function table(GDB) sFoo:: Foo (this=0xbffff02c) at test03. cpp:66Class Foo {(GDB) Smain () at test03. cpp: - -Foo. Func();(GDB) sFoo:: Func (this=0xbffff02c) at test03. cpp:99{cout <<"virtual function in Foo!"<< Endl; }(GDB) svirtual functioninchFoo!main () at test03. cpp: - -Return0;(GDB) s -} (GDB)
The fourth case is similar to the third case, if the object of the same class is initialized directly, it can be done by bitwise copy; If the base class object is initialized with a derived class object, the compiler will reset the virtual base Clas A pointer to S;
C + + constructor semantics--default copy constructor