显式析构函数调用不起作用

时间:2016-08-12 09:21:43

标签: c++ unit-testing g++ destructor

我的c ++类的简化版本:

class Class
{
public:
    Class(uint32_t size_, uint8_t val_) buf(NULL), size(size_)
    {
         buf = new uint8_t[size];
         memset(buf, val_, size);
    }
    ~Class()
    {
        if(buf != NULL)
        {
            delete[] buf;
            buf = NULL;
            size = 0;
        }
    }
    void FakeDtor()
    {
        if(buf != NULL)
        {
            delete[] buf;
            buf = NULL;
            size = 0;
        }
    }

    protected:
        uint8_t* buf;
        uint32_t size;
}

我的单位测试代码:

TEST_F(Classtest, testDestructor) 
{
    Class *buff = new Class(10,10);
    ASSERT_NE(buff->getData(), (uint8_t*)NULL);

    buff->~Class(); // buff->FakeDtor();

    ASSERT_EQ(buff->getData(), (uint8_t*)NULL);
}

当我使用msbuild编译代码并运行UT时 - 显式调用dtor工作并且UT传递。当我使用g ++使用gtest编译和运行UT时 - 显式调用dtor似乎失败了,因为断言失败后。当我使用FakeDtor()而不是~Class()时,UT会在Windows和Linuix上传递。在Linux下调用它时,什么可能导致dtor不执行?

1 个答案:

答案 0 :(得分:2)

在运行非平凡的析构函数之后读取类的内容会调用未定义的行为。对象所存在的内存仍然存在并不重要,因为你没有null它,对象本身已经死了,不能再使用了。

如果你这样做,一切都被允许发生。手头的概念类似于悬空指针/引用,例如参见this

这是UB包含"如果析构函数设置数据成员值,因为没有有效的程序将能够读取这些值,编译器可以优化这些成员的设置。&#34 ; 正如@hvd comment中指出的那样。