C++构造函数语意学——默认拷贝构造函数
2015-03-03 11:13
267 查看
概述
使用 class object 时,在以下三种情况会以一个 object 的内容作为另一个 class object 的初值,即用到拷贝构造函数:定义一个 class object 并对其进行初始化;
class object 作为一个参数传递给函数;
class object 作为函数的返回值;
若用户没有显示声明或定义拷贝构造函数,则 C++ 在 必要 时为 class 声明或定义隐式拷贝构造函数,若出现以下的情况时,该拷贝构造函数是 trivial 的:
their class has no virtual functions and no virtual base class(es).
all direct base classes and non-static data members of their class have trivial constructors.
Otherwise, the copy constructor are non-trivial. Implicitly-declared non-trivial copy constructor.
默认拷贝构造函数
在以下四种情况下,编译器会合成一个 non-trivial 的默认拷贝构造函数:当 class 内含一个具有 copy constructor 的 member object;
当 class 继承自一个具有 copy constructor 的 base class;
当 class 声明有 virtual functions;
当 class 派生自 virtual base class(es);
前面两种情况,编译器必须将 member 或 base class 的 copy constructor 放置在默认拷贝构造函数中,以下例子同时满足这两个情况:
#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; }
执行结果:编译器在合成的拷贝构造函数中调用了两次 Foo 类的拷贝构造函数;
(gdb) r Starting program: ./test02 Breakpoint 1, main () at test02.cpp:20 20 Word ba; (gdb) s Word::Word (this=0xbffff020) at test02.cpp:11 11 class Word: public Foo { (gdb) s Foo::Foo (this=0xbffff020) at test02.cpp:7 7 Foo() {} (gdb) s Foo::Foo (this=0xbffff024) at test02.cpp:7 7 Foo() {} (gdb) s main () at test02.cpp:21 21 Word bb = ba; (gdb) s Word::Word (this=0xbffff028) at test02.cpp:11 11 class Word: public Foo { (gdb) s Foo::Foo (this=0xbffff028, foo=...) at test02.cpp:8 8 Foo(const Foo &foo) { cout << "Foo's copy construct!" << endl; } (gdb) s Foo's copy construct! Foo::Foo (this=0xbffff02c, foo=...) at test02.cpp:8 8 Foo(const Foo &foo) { cout << "Foo's copy construct!" << endl; } (gdb) s Foo's copy construct! main () at test02.cpp:22 22 return 0; (gdb) s 23 } (gdb)
第三种情况,若是相同 class 的 object 直接的初始化,可以采用 bitwise copy 方式进行,因为 vptr 指向相同的虚函数表;若是使用派生类 object 初始化 基类 object 时,则编译器会重新设定 class object 的 virtual table 的指针,因为不同类的 vptr 指向各自的虚函数表;
#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; // 相同类对象之间初始化,vptr直接复制,指向相同的virtual function table b2.func(); Foo foo = b1; // 不同类对象之间初始化,发生切割,vptr不直接复制,指向不同的virtual function table foo.func(); return 0; }
执行结果:
(gdb) b 19 Breakpoint 1 at 0x8048809: file test03.cpp, line 19. (gdb) r Starting program: /home/nifengweijifen/linuxStudy/ObjectModel/chap02/test03 Breakpoint 1, main () at test03.cpp:19 19 Word b1; (gdb) s Word::Word (this=0xbffff024) at test03.cpp:12 12 class Word: public Foo { (gdb) s Foo::Foo (this=0xbffff024) at test03.cpp:6 6 class Foo { (gdb) s main () at test03.cpp:20 20 Word b2 = b1; //相同类之间的初始化,直接复制 vptr,指向相同的virtual function table (gdb) s Word::Word (this=0xbffff028) at test03.cpp:12 12 class Word: public Foo { (gdb) s Foo::Foo (this=0xbffff028) at test03.cpp:6 6 class Foo { (gdb) s main () at test03.cpp:21 21 b2.func(); (gdb) s Word::func (this=0xbffff028) at test03.cpp:15 15 { cout << "virtual function in Bar!" << endl; } (gdb) s virtual function in Word! main () at test03.cpp:23 23 Foo foo = b1; // 不同类之间的初始化,发生切割,vptr不直接复制,指向不同的virtual function table (gdb) s Foo::Foo (this=0xbffff02c) at test03.cpp:6 6 class Foo { (gdb) s main () at test03.cpp:24 24 foo.func(); (gdb) s Foo::func (this=0xbffff02c) at test03.cpp:9 9 { cout << "virtual function in Foo!" << endl; } (gdb) s virtual function in Foo! main () at test03.cpp:25 25 return 0; (gdb) s 26 } (gdb)
第四种情况和第三种情况相似,若是相同 class 的 object 直接的初始化,可以采用 bitwise copy 方式进行;若是使用派生类 object 初始化 基类 object 时,则编译器会重新设定 virtual base class 的指针;
相关文章推荐
- 【C++对象模型】构造函数语意学之二 拷贝构造函数
- 【C++对象模型】构造函数语意学之二 拷贝构造函数
- C++拷贝构造函数(包括默认拷贝构造函数以及深拷贝、浅拷贝)
- C++默认的拷贝构造函数
- C++学习体会--构造函数,析构函数,拷贝构造函数
- C++编译器何时提供默认的构造函数和拷贝构造函数 .
- 浅析C++的构造函数,拷贝构造函数和赋值运算符
- C++ 有关赋值构造函数 拷贝构造函数 自动型别转换
- C++构造 函数,析构函数,拷贝构造函数,赋值构造函数,一个内存错误例子!
- C++对象模型 ch2 构造函数语意学
- C++中的构造函数,拷贝构造函数和赋值运算
- C++ 编译器默认构造函数奇怪问题
- 深入探索C++对象模型笔记之三 —— 构造函数语意学 (Default Constructor的建构操作)
- C++空类默认生成的构造函数
- C++:实例解析构造函数、析构函数、拷贝构造函数等
- C++默认的构造函数以及运算符重载关键点
- C++学习笔记(构造函数和拷贝构造函数)
- 深入探索C++对象模型笔记之四 —— 构造函数语意学 (Copy Constructor的建构操作)
- C++编译器何时提供默认的构造函数和拷贝构造函数
- c++默认的拷贝构造函数是浅拷贝