C++构造函数语意学——默认拷贝构造函数
来源:互联网 发布:广州君海网络热血霸业 编辑:程序博客网 时间:2024/05/09 01:01
概述
使用 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) 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)
第三种情况,若是相同 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 19Breakpoint 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; //相同类之间的初始化,直接复制 vptr,指向相同的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; // 不同类之间的初始化,发生切割,vptr不直接复制,指向不同的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)
第四种情况和第三种情况相似,若是相同 class 的 object 直接的初始化,可以采用 bitwise copy 方式进行;若是使用派生类 object 初始化 基类 object 时,则编译器会重新设定 virtual base class 的指针;
1 0
- C++构造函数语意学——默认拷贝构造函数
- C++构造函数语意学——默认构造函数
- 拷贝构造函数 copy constructor 语意学
- 构造函数语意学
- 构造函数语意学(一):默认构造函数
- Chap2-构造函数语意学
- 构造函数之语意学
- 第二章 构造函数语意学 编译器何时合成拷贝构造函数?
- 默认拷贝构造函数
- 拷贝构造函数--默认拷贝构造函数
- 第二章 构造函数语意学 编译器何时生成默认构造函数?
- 构造函数语意学和Data语意学
- 构造函数语意学----程序转化语意学
- 今天学构造函数,析构函数,默认构造函数,拷贝构造函数,颇有所得。
- 构造、解构、拷贝语意学
- 构造、析构、拷贝语意学
- 第2章构造函数语意学
- 构造函数语意学----初始化列表
- 应用于文本分类问题的TF-IDF改进方法
- Android自动化编译设置AndroidManifest.xml中package值(包名)
- ppt转换成pdf乱码解决方法
- 去除C++String的首尾空格
- iostat命令详解
- C++构造函数语意学——默认拷贝构造函数
- Linux下配置OpenLDAP服务记录
- 【Android-小技巧】EditText设置光标
- Lua 使用过程的一个理解(lua_pcall(L, 0, 0, 0);)
- GUI与命令行------永远的争议
- 安装compass报错问题
- SurfaceView
- 寒假14项目1——动态数组体验(修改5)
- ppt转换成pdf乱码解决方法