模板化的手动析构函数调用不起作用

时间:2019-07-15 18:36:22

标签: c++ pointers templates destructor

我想销毁模板对象,但是要保留分配的内存。不幸的是,从未调用过对象的析构函数,并且单步执行代码会跳过手动调用。

=COUNTIFS(A2:A10,">"&B2:B10, C2:C10,"1/1/2018")

我已经在VS 2017和在线C ++编译器中对此进行了测试。两者都跳过指针->〜type();单步执行时,永远不会调用析构函数。

编辑:重写现在可以重现该错误的代码。

2 个答案:

答案 0 :(得分:1)

它确实调用了析构函数。

#include <iostream>

class Type
{
    public:
    ~Type()
    {
        std::cout<< __FUNCTION__ << "\n";
    }
};


template <typename type> class MyClass
{
    private:

        type *data;

    public:

        MyClass();
        ~MyClass(){}

        void Replace();
};


template <typename type> MyClass<type>::MyClass()
{
    data =  reinterpret_cast<type *>(new char[sizeof(type)]);;
}


template <typename type> void MyClass<type>::Replace()
{
    type *pointer = &data[0];
    pointer->~type();

    //Fill with replacement data
}
int main()
{

    MyClass<Type> myClass;

    std::cout <<"Before destruction\n";
myClass.Replace();
std::cout << "After destruction\n";
    return 0;

}

答案 1 :(得分:0)

要允许模板一般处理类型,即使类型不是类类型(但不适用于数组类型),C ++也允许使用obj.~type()ptr->~type()语法。其含义与该类型的自动对象在其作用域结尾处发生的操作相同:如果它是类类型,则将调用析构函数,否则,则不会发生任何事情。对于类型不是类类型的情况,此语法称为pseudo-destructor

现在看您的示例,您正在使用类模板特殊化TestClass<MyClass*>。因此,在实例化TestClass<type>::Replace()的成员定义时,typeMyClass*的别名。声明

type *pointer = reinterpret_cast<type *>(&data[0]);

定义类型为type*的变量,即MyClass**。 (右侧令人困惑:&data[0]data相同,假定它指向某物,并且两个表达式都已经具有类型type*。)

声明

pointer->~type();

表示要销毁type指向的pointer类型的对象。也就是说,它说要销毁类型为MyClass*的对象*pointerMyClass*不是类类型;它是指针类型。因此,这是对伪析构函数的调用,绝对没有任何反应。

没有足够的上下文可以确定如何解决此问题,但是也许您需要使用TestClass<MyClass>而不是TestClass<MyClass*>? (此外,在实际代码中,请不要忘记“五法则” /“三法则”。)