2017-07-07 156 views
1

学习新增/删除过载时,我无法理解一些问题。 问题:重载操作符new(),为什么构造函数被调用两次?

  1. 为什么在构造函数,析构函数在删除之前调用new?
  2. 为什么在使用:: new时会调用两次构造函数?

我这里附加代码:


#include<iostream> 

using namespace std; 

class MyClass 
{ 
public: 
    MyClass() { 
     cout << "My Class is Constructed !" << endl; 

    } 

    ~MyClass() { cout << "My Class is Deleted ! " << endl; } 

    static void *operator new(size_t Size) 
    { 
     cout << "new call" << endl; 
     MyClass *p = ::new MyClass; 
     return p; 
    } 
    static void operator delete(void *p) 
    { 
     cout << "delete call" << endl; 
     ::delete p; 
    } 

}; 
int main() 
{ 
    MyClass *p = new MyClass; 
    delete p; 
    cin.get(); 
    return 0; 
} 

output: 
new call 
My Class is Constructed ! 
My Class is Constructed ! 
My Class is Deleted ! 
delete call 

+7

你不应该在'MyClass :: operator new'里面执行':: new MyClass'。这个函数的目的是在不调用构造函数的情况下分配内存,但是你调用了一个构造函数(这就是为什么你会看到2个构造函数调用 - 对应于'new'表达式的两个用法)。 –

+0

回答你的问题1,显然必须先获得存储空间,然后才能构建对象;并且在释放存储器之前必须销毁对象 –

+1

@ M.M:回答部分如下。 –

回答

3

为什么发生这种情况的原因是因为当你分配一些与new,分配建设分两个阶段进行。第一个是实际分配,第二个是通过安置新建筑。

您提供的重载仅用于分配内存(因此参数为size_t),但您可以在类上调用new,该类将执行上述两个步骤。你应该只在该函数中分配内存。所以改变你的功能

static void *operator new(size_t size) 
{ 
    return ::operator new(size); 
} 

而且你会看到只有一次构造的类。

+0

所以,删除someting也有两个阶段,破坏和释放内存?为什么析构函数只被调用一次? – JackChen

+1

@JackChen因为你只调用它一次,就像构造函数被调用两次,因为你调用它两次。 – EJP

+0

@JackChen EJP是对的,如果你在'operator delete'的重载中注意到,你已经在一个void指针上调用了':: delete',这只是释放内存,你还没有尝试'static_cast' void指针指向MyClass的指针,然后调用析构函数,这就是为什么你只能得到一个析构函数调用 – Curious

相关问题