C ++ 11 Destructor = delete

时间:2015-01-29 08:48:10

标签: c++ c++11 destructor

我已经看到构造函数=删除解释here,但我想知道我是否也应该禁止析构函数调用。我试图使用这样的类:

class A
{
public:
    static bool foo(const char* filePath);
    static void foo(const int something);
private:
    A() = delete;
    ~A();
};

我是否也应该像~A() = delete;那样写作?它甚至重要吗?

3 个答案:

答案 0 :(得分:9)

~A() = delete;是多余的,因为你不能创建一个对象,所以没有必要担心析构函数。

事实上,您的代码甚至不需要A() = delete;,因为所有班级成员都是static
正如Luchian在评论中正确提到的那样,class最好被声明为namespace。根据要求,可以为extern / static提供基础数据。

答案 1 :(得分:3)

不,没关系。您也可以将其删除,但如果构造函数被删除,则删除析构函数将不会执行任何其他操作。

第一个(已删除的构造函数)告诉您无法创建对象。第二个(删除的析构函数)告诉我们不可能销毁对象。

请注意,可以使用各种黑客“创建”和初始化对象,但在这些情况下,所有投注均已关闭,并且程序正在执行未定义的行为。

答案 2 :(得分:1)

要在此处添加其他答案,您可能需要将析构函数声明为已删除,而不是私有且未实现。这是因为,即使删除了private构造函数,您仍然可以使用聚合初始化创建实例:

Demo

class A
{
public:
    static bool foo(const char* filePath);
    static void foo(const int something);
private:
    A() = delete;
};

int main(){
   A a{}; // whoops I just created an instance
}

但是,如果您将析构函数声明为已删除,则默认构造或聚合初始化都将无法工作-由于编译器无法为A 调用析构函数,因此无法编译>

Demo

class A
{
public:
    static bool foo(const char* filePath);
    static void foo(const int something);
    ~A() = delete;
};

int main(){
   A a{}; // fails
   A b; // fails
}

由于您已经将析构函数声明为私有且未实现,因此所有其他内容都是多余的。 C ++ 11使您变得更轻松,因为您不需要private,只需在析构函数上使用= delete。最好将析构函数声明为Deleted,因为它会与其他程序员交流,您从未打算实现它。拥有它的方式,某些程序员最初可能会认为您只是忘了包含实现。


您将要声明两者均为默认构造函数,并且将析构函数声明为已删除,以防止动态内存分配(通过new或{{3 }}),因为否则调用delete或显式调用析构函数将导致编译错误。如果我们方便地忘记了,那就没事了:

placement new

class A
{
public:
    static bool foo(const char* filePath);
    static void foo(const int something);
    ~A() = delete;
};

int main(){
    A* a = new A(); // whoops I created an instance
    // we leak memory
}

Demo

但是同时删除构造函数和析构函数可以防止这种情况:

Placement new demo

class A
{
public:
    static bool foo(const char* filePath);
    static void foo(const int something);
    ~A() = delete;
    A() = delete;
};

int main(){
    A* a = new A(); // doesnt compile
    A b{}; // doesn't compile
    A c; // doesn't compile
}

请参阅[class.dtor]:“如果删除了可能调用的析构函数,或者在调用的上下文中无法访问该程序,则程序格式错误。”