7
. 构造和析构的直接调用方式
通过指针不可以直接调用构造函数,但可以直接调用析构函数。可以通过placement new
来直接调用构造函数。
1 | struct A |
8
. array new/delete
new []/delete[]
本质调用malloc/free
。malloc/free
细节:
除了分配给定的内存之外,还会有
cookie
——用来记录分配数组的长度,查看cookie
中的长度,然后调用适当次数的析构函数所谓内存泄漏
对于一个
new []
,需要有相应的delete []
,本质上cookie
记录了free
本身需要释放的内存大小,泄露则发生在调用的析构函数次数上:如果对象含有指针的data member
,指向堆上的内存,则意味着析构函数是nontrival
,需要再析构函数中释放指针指向的内存,反之则是trival
的,而析构函数的调用次数,则会影响指针指向的内存部分的泄露。
9
. placement new
标准不允许直接用指针调用构造函数,但给出了另一种调用语法,可以在现有的对象的内存中调用构造函数,它不会分配新的内存。这也是没有对应的placement delete
的原因。
10
. C++
程序分配内存的途径
从图中可以看出,当出现new Foo(x)
后,编译器会检查Foo
这个类有没有实现operator new(size_t)
的static
函数,如果有就会调用Foo
这个版本的operator new
,如果没有就调用全局的::operator new
,delete
也是如此。
所以可以为一个类单独实现operator new
和operator delete
。也可以重载全局的operator new/delete
,但很少这么做,因为全局的版本是照顾所有的类。
11
. 探究operator new
1 | int main() |
12
. 重载::operator new/delete
上面说了,重载全局的operator new/delete
影响深远,谨慎使用。但可以重载,方法是在非namespace
中声明和全局版本相同的函数签名。
1 | using namespace std; |