前言:之前在搓高并发内存池的时候就在想,类对象不能调用自身的构造函数,那直接申请内存出来的类对象岂不是很难受,然后我这两天仔细研究了一下,发现其实构造函数也可以显示去调用,而且含不限量,故做此文
在c++中一个类对象不能直接调用自身的构造
class A {
public:A() {cout << this << endl;cout << "构造函数" << endl;}~A() {cout << this << endl;cout << "析构函数" << endl;}
private:int _a;double _b;char* _c;
};int main() {cout << "a对象创建" << endl;{A* a = (A*)malloc(sizeof(A));}cout << "a对象销毁" << endl;system("pause");
}
显然没有析构也没有构造
这时我们可以通过new的一种高级用法来显示去调用构造析构
语法如下
A* obj = new (a) A;
请注意这条语句没有构造新的A类型
class A {
public:A() {cout << this << endl;cout << "构造函数" << endl;}~A() {cout << this << endl;cout << "析构函数" << endl;}
private:int _a;double _b;char* _c;
};int main() {cout << "a对象创建" << endl;{A* a = (A*)malloc(sizeof(A));A* obj = new (a) A;cout << a << endl;cout << obj << endl;}cout << "a对象销毁" << endl;system("pause");
}
看到调用构造函数时obj的值与a的值是相同的,所以它的底层其实是偷偷摸摸去调了构造,然后把a拷贝给obj
上一种情况是指针,这里使用类再来一次
class A {
public:A() {cout << this << endl;cout << "构造函数" << endl;}~A() {cout << this << endl;cout << "析构函数" << endl;}
private:int _a;double _b;char* _c;
};int main() {cout << "a对象创建" << endl;{//A* a = (A*)malloc(sizeof(A));//A* obj = new (a) A;//cout << a << endl;//cout << obj << endl;A a;cout << "a 的地址为 : " << &a << endl;cout << "这里显示的调一次构造" << endl;new (&a)A;}cout << "a对象销毁" << endl;system("pause");
}
看一下反汇编,按我的水平进行一次粗浅的理解的话就是去调用一个拷贝,然后调用构造,较于普通new的话不需要额外开辟空间(想了解更仔细的话可以问问ai,不要信我胡诌的)
new (&a)A;
00007FF7A6370037 lea rdx,[rbp+8]
00007FF7A637003B mov ecx,18h
00007FF7A6370040 call operator new (07FF7A6361668h)
00007FF7A6370045 mov qword ptr [rbp+0F8h],rax
00007FF7A637004C mov rcx,qword ptr [rbp+0F8h]
00007FF7A6370053 call A::A (07FF7A63618D9h) new (A);
00007FF7A6370058 mov ecx,18h
00007FF7A637005D call operator new (07FF7A6361069h)
00007FF7A6370062 mov qword ptr [rbp+138h],rax
00007FF7A6370069 cmp qword ptr [rbp+138h],0
00007FF7A6370071 je __$EncStackInitStart+14Ah (07FF7A6370099h)
00007FF7A6370073 mov edx,18h
00007FF7A6370078 mov rcx,qword ptr [rbp+138h]
00007FF7A637007F call A::__autoclassinit2 (07FF7A63618DEh)
00007FF7A6370084 mov rcx,qword ptr [rbp+138h]
00007FF7A637008B call A::A (07FF7A63618D9h)
00007FF7A6370090 mov qword ptr [rbp+148h],rax
00007FF7A6370097 jmp __$EncStackInitStart+155h (07FF7A63700A4h)
00007FF7A6370099 mov qword ptr [rbp+148h],0
00007FF7A63700A4 mov rax,qword ptr [rbp+148h]
00007FF7A63700AB mov qword ptr [rbp+118h],rax
感谢观看