解构主义者很懒,为什么?

时间:2014-03-16 20:30:13

标签: c++

对象的真正毁灭是什么? 如果您这样做:

class K {
public:
   K (int m) {v = m;}
   int v;
};


Class * x = reinterpret_cast <K*> (:: operator new (sizeof (K)));
new ((void *) x) K (2);


x-> ~ C ();
cout << x-> v; / / result: 2

:: operator delete ((void *) v);

解构主义者没有! (?)为什么?

3 个答案:

答案 0 :(得分:3)

你期望它做什么(抛开错别字)?你有一个不需要任何破坏的POD类型。尝试使用更丰富的东西来做同样的事情,比如说,在那里放一个std::string,析构函数实际上会做点什么。

然后,将这些实验放在一边,如果在接下来的二十年中在一个地方,你确实需要放置新的和显式调用的析构函数,在你需要的析构函数中放入一些调试输出并检查它是否实际被调用。

答案 1 :(得分:3)

您正在处理两组想法:

  1. 构建和销毁对象
  2. 记忆的分配和释放。
  3. 了解如何正确组合这些内容非常重要。

    假设你有一个功能:

    void f1()
    {
       // Construct an object.
       // The constructor gets called.
       K k(10);
    
       // Do something with the object.
    
       // Done with the function
       // The object k gets destructed.
       // The destructor gets called.
    }
    

    在此函数中,您将在堆栈上构造对象。从函数返回时,析构函数会自动调用。内存将自动从堆栈中分配和释放。

    现在,让我们看看另一个功能。

    void f2()
    {
       // Allocate memory for the object.
       // Use that Construct an object .
       // The constructor gets called.
       K* k = new K(10);
    
       // Do something with the object.
    
       // Done with the function
       // Delete the object.
       // The destructor gets called.
       // Deallocate the memory.
       delete k;
    }
    

    此函数中的这一行K* k = new K(10);执行两个操作 - 它从堆中为对象分配内存,并调用构造函数来构造对象。

    delete k;也结合了两个操作。它首先调用析构函数然后从堆中释放内存。如果您没有delete k;,该函数将泄漏由new K(10)分配的内存。

    在这里,我们使用了newdelete运算符。

    现在看一下使用全局operator newoperator delete函数。

    void f3()
    {
       // Allocate memory for the object from the heap.
       void* p = ::operator new(sizeof(K));
    
       // At this point, an object of type K has not been constructed yet.
    
       K* k1 = reinterpret_cast<K*>(p);
       // Using the reinterpret_cast to treat the `void*` as a `K*` does not
       // change that fact. An object of type K has not yet been constructed still.
    
       K* k2 = new (p) K(10);
       // Use placement new operator to construct K.
       // At this point, an object of type K has been constructed by calling
       // K's constructor using the memory pointed to by p.
    
    
       // Do something with the object.
    
       // Done with the function.
       // Now it's time to do the necessary things to release resources back to
       // the system.
    
       // Do not use `delete K` at this point.
       // Whenever you use the placement new operator, call the destructor explicitly.
       // This calls the destructor ~K(), but does not deallocate memory from heap.
       k2->~K();
    
       // Deallocate the memory heap.
       ::operator delete(p);
    }
    

答案 2 :(得分:1)

  

解构主义者没有! (?)为什么?

因为在这种情况下它是空的。你期望它到底做了什么?