C ++ constructor semantics-default copy constructor, constructor Semantics
Overview
When using class object, the content of one object is used as the initial value of another class object in the following three cases, that is, the copy constructor is used:
If you do not display a declaration or define a copy constructorRequiredClass declaration or implicit copy constructor. if the following conditions occur, the copy constructor is trivial:
Default copy constructor
In the following four cases, the compiler combines a non-trivial default copy constructor:
In the first two cases, the compiler must place the copy constructor of the member or base class in the default copy constructor. The following example meets both of the following conditions:
#include <iostream>using namespace std;class Foo {public: Foo() {} Foo(const Foo &foo) { cout << "Foo's copy construct!" << endl; }};class Word: public Foo {public: int x; Foo foo;};int main(){ Word ba; Word bb = ba; return 0;}
Execution result: the compiler calls the copy constructor of the Foo class twice in the merged copy constructor;
(gdb) rStarting program: ./test02 Breakpoint 1, main () at test02.cpp:2020 Word ba;(gdb) sWord::Word (this=0xbffff020) at test02.cpp:1111 class Word: public Foo {(gdb) sFoo::Foo (this=0xbffff020) at test02.cpp:77 Foo() {}(gdb) sFoo::Foo (this=0xbffff024) at test02.cpp:77 Foo() {}(gdb) smain () at test02.cpp:2121 Word bb = ba;(gdb) sWord::Word (this=0xbffff028) at test02.cpp:1111 class Word: public Foo {(gdb) sFoo::Foo (this=0xbffff028, foo=...) at test02.cpp:88 Foo(const Foo &foo) { cout << "Foo's copy construct!" << endl; }(gdb) sFoo's copy construct!Foo::Foo (this=0xbffff02c, foo=...) at test02.cpp:88 Foo(const Foo &foo) { cout << "Foo's copy construct!" << endl; }(gdb) sFoo's copy construct!main () at test02.cpp:2222 return 0;(gdb) s23 }(gdb)
In the third case, if objects of the same class are directly initialized, bitwise copy can be used, because vptr points to the same virtual function table. If a derived class object is used to initialize a base class object, the compiler will reset the virtual table pointer of the class object because vptr of different classes points to their respective virtual function tables;
# Include <iostream> using namespace std; class Foo {public: virtual void func () {cout <"virtual function in Foo! "<Endl ;}}; class Word: public Foo {public: void func () {cout <" virtual function in Word! "<Endl ;}; int main () {Word b1; Word b2 = b1; // initialize between the same class objects, and copy the vptr directly, point to the same virtual function table b2.func (); Foo foo = b1; // different class objects are initialized and cut. vptr does not directly copy and points to different virtual function table foo. func (); return 0 ;}
Execution result:
(Gdb) B 19 Breakpoint 1 at 0x8048809: file test03.cpp, line 19. (gdb) rStarting program:/home/nifengweijifen/linuxStudy/ObjectModel/chap02/test03 Breakpoint 1, main () at test03.cpp: 1919 Word b1; (gdb) sWord :: word (this = 0xbffff024) at test03.cpp: 1212 class Word: public Foo {(gdb) sFoo: Foo (this = 0xbffff024) at test03.cpp: 66 class Foo {(gdb) smain () at test03.cpp: 2020 Word b2 = b1; // initialize between the same classes and directly copy v Ptr pointing to the same virtual function table (gdb) sWord: Word (this = 0xbffff028) at test03.cpp: 1212 class Word: public Foo {(gdb) sFoo :: foo (this = 0xbffff028) at test03.cpp: 66 class Foo {(gdb) smain () at test03.cpp: 2121 b2.func (); (gdb) sWord: func (this = 0xbffff028) at test03.cpp: 1515 {cout <"virtual function in Bar! "<Endl;} (gdb) svirtual function in Word! Main () at test03.cpp: 2323 Foo foo = b1; // initialization between different classes, where a cut occurs and vptr is not directly copied, pointing to different virtual function table (gdb) sFoo :: foo (this = 0xbffff02c) at test03.cpp: 66 class Foo {(gdb) smain () at test03.cpp: 2424 foo. func (); (gdb) sFoo: func (this = 0xbffff02c) at test03.cpp: 99 {cout <"virtual function in Foo! "<Endl;} (gdb) svirtual function in Foo! Main () at test03.cpp: 2525 return 0; (gdb) s26} (gdb)
The fourth case is similar to the third case. If an object of the same class is directly initialized, bitwise copy can be used. If a base class object is initialized using a derived class object, the compiler will reset the pointer of the virtual base class;