操作员如何“删除此内容”确切地如何做?

时间:2019-07-10 06:36:45

标签: c++ delete-operator

我只是测试操作员有关“删除此”的操作。使用句柄系统调用“ new / delete”将丢失一个覆盖删除功能的调用。

handle函数类似于:

inline void* operator new(size_t size)
{
    void* p = ::malloc( size );
    fprintf( stderr, "new size %ld: %p\n", size, p );
    return p; 
}

inline void* operator new[]( size_t size )
{
    void* p = ::malloc( size );
    fprintf( stderr, "new size[] %ld: %p\n", size, p );
    return p; 
}

inline void  operator delete(void* p)    
{
    fprintf( stderr, "delete: %p\n", p );
    ::free(p); 
}

inline void  operator delete[](void* p)  
{
    fprintf( stderr, "delete []: %p\n", p );
    ::free(p); 
}

和测试班级:

class A
{
    public:
        A() : a(NULL)
        {
            printf( "A construct\n" );
            a = new int[100];
        }

        ~A()
        {
            printf( "A destruct \n" );
            freeA();
        }

        void freeA()
        {
            if ( a ) { delete [] a; a = NULL; }
        }

        void release()
        {
            delete this;
        }

    private:
        int*    a;
};

当我打电话

A* a = new A();
a->release();

结果是:

new size 8: 0x5642fc1c4e70
A construct
new size[] 400: 0x5642fc1c52a0
A destruct 
delete []: 0x5642fc1c52a0

缺少有关A(0x5642fc1c4e70)的删除呼叫,为什么?

4 个答案:

答案 0 :(得分:0)

我刚发现问题:使用内联,运算符delete(void * p)根本无法调用。但是delete [](void * p)可以。 现在我将关闭它。

答案 1 :(得分:0)

https://timsong-cpp.github.io/cppwp/replacement.functions#3

  

使用程序的定义代替默认版本   由实现([support.dynamic])提供。这样的替换   发生在程序启动之前([basic.def.odr],[basic.start])。的   程序的声明不应指定为内联。无诊断   是必需的。

那是规则。不允许内联。这就是您缺少一个删除操作的原因,并且该删除操作无需内联说明符。

答案 2 :(得分:0)

我在c ++ 14以下运行您的代码,可以正确调用您的delete运算符。

https://onlinegdb.com/S1zAgzXbB

但是,在版本c ++ 14(包括c ++ 14)上运行,然后需要将代码从inline void operator delete(void* p)更改为inline void operator delete(void* p,std::size_t sz)或删除inline关键字。那么您的代码将正确运行

https://onlinegdb.com/BJ3hMz7WH

希望它将对您有所帮助。

答案 3 :(得分:0)

由于已定义析构函数,因此无需定义释放函数。直接在实例的指针上使用delete

代替

A* a = new A();
a->release();

您将拥有

A* a = new A();
delete a;

删除a将调用〜A()析构函数