cpp 构造与析构(侯捷)
inline(内联函数)
若在函数体内定义完成,变为内联函数的候选人
inline 函数运行更快,inline 只是建议,具体是否使用由编译器决定拷贝构造
拷贝赋值
包含指针需要单独实现,不可用默认的
虚函数
虚函数表
构造函数
函数重载 :由编译器负责将函数命名唯一化,使用函数名和参数 有关
1 |
|
尽量inline由编译器决定
1 | inline double imag(const conplex& x){ |
友元
同一个class的各个objects互为友元
tips
尽量使用引用传递,入参以及返回值
引用实际上是由编译器使用指针实现
返回值不能使用引用,若返回的值在离开函数后不存在
使用引用的方式传递着,无需知道接受者是以引用的方式接受的
1 | inline complex& |
操作符重载
成员函数
1 | complex c1; |
1 |
|
非成员函数
临时对象
特殊操作符要使用全局的操作符重载
cout<< conj(c1);
cout<< c1<< conj(c1);
1 | // 全局函数 |
拷贝构造&赋值构造
1 | class String |
虚函数与虚函数表
图示
静态绑定
满足以下条件
- 指针
- 向上转型
- 调用的是虚函数
编译成图示形式
1 | (*(p->vptr)[n])(p); |
动态绑定的实现原理
1 | class CMyDoc:public CDocument{ |
当我们调用OnFileOpen时,会将this指针传入,调用的Serialize方法,会在虚函数表上进行查找,虚函数表会讲地址重新定位为CMyDoc 所重写的函数地址
举例说明
1 | B b; |
new与delete的重载
全局函数重载
1 | //自定义malloc |
类内部函数重载
1 | class Foo{ |
例子
1 | class Foo{ |
- clang mac 64 位电脑运行结果
1
2
3
4
5
6
7
8
9cout<<"sizeof(int)"<<sizeof(int)<<endl;
cout<<"sizeof(long)"<<sizeof(long)<<endl;
cout<<"sizeof(string)"<<sizeof(string)<<endl;
cout<<"sizeof(Foo)"<<sizeof(Foo)<<endl;
Foo* p = new Foo(7);
delete p;
Foo* pArray= new Foo[5];
delete[] pArray;析构函数为非虚函数版本
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20sizeof(int)4
sizeof(long)8
sizeof(string)24
sizeof(Foo)40
call my new size=40
ctor.this=0x7ff42a405990 id=7 _data0 stirng=
dtor.this=0x7ff42a405990 _id=7
call my delete size=40
call my new[] size=208
default ctor.this=0x7ff42a4059c8 id=0 _data0 stirng=
default ctor.this=0x7ff42a4059f0 id=0 _data0 stirng=
default ctor.this=0x7ff42a405a18 id=0 _data0 stirng=
default ctor.this=0x7ff42a405a40 id=0 _data0 stirng=
default ctor.this=0x7ff42a405a68 id=0 _data0 stirng=
dtor.this=0x7ff42a405a68 _id=0
dtor.this=0x7ff42a405a40 _id=0
dtor.this=0x7ff42a405a18 _id=0
dtor.this=0x7ff42a4059f0 _id=0
dtor.this=0x7ff42a4059c8 _id=0
call my[] delete size=208析构函数为非虚函数版本
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23sizeof(int)4
sizeof(long)8
sizeof(string)24
sizeof(Foo)48
call my new size=48
ctor.this=0x7ff9f4c05990 id=7 _data0 stirng=
dtor.this=0x7ff9f4c05990 _id=7
call my delete size=48
call my new[] size=248
default ctor.this=0x7ff9f4c059c8 id=0 _data0 stirng=
default ctor.this=0x7ff9f4c059f8 id=0 _data0 stirng=
default ctor.this=0x7ff9f4c05a28 id=0 _data0 stirng=
default ctor.this=0x7ff9f4c05a58 id=0 _data0 stirng=
default ctor.this=0x7ff9f4c05a88 id=0 _data0 stirng=
dtor.this=0x7ff9f4c05a88 _id=0
dtor.this=0x7ff9f4c05a58 _id=0
dtor.this=0x7ff9f4c05a28 _id=0
dtor.this=0x7ff9f4c059f8 _id=0
dtor.this=0x7ff9f4c059c8 _id=0
call my[] delete size=248
Process finished with exit code 0
new(),delete()
- new()
- 可以重载new 但要求new都有不同的参数
- 而且其中的第一个参数必须是size_t size
- delete()
- 可以写出多个delete,但不会被默认调用,只有在默认版本的new 抛出异常时才会被调用
例子
1 | class Foo{ |
例子结果
并没有调用对应的析构函数
1 | Foo::Foo() |