我已经看到构造函数=删除解释here,但我想知道我是否也应该禁止析构函数调用。我试图使用这样的类:
class A
{
public:
static bool foo(const char* filePath);
static void foo(const int something);
private:
A() = delete;
~A();
};
我是否也应该像~A() = delete;
那样写作?它甚至重要吗?
答案 0 :(得分:9)
~A() = delete;
是多余的,因为你不能创建一个对象,所以没有必要担心析构函数。
事实上,您的代码甚至不需要A() = delete;
,因为所有班级成员都是static
。
正如Luchian在评论中正确提到的那样,class
最好被声明为namespace
。根据要求,可以为extern
/ static
提供基础数据。
答案 1 :(得分:3)
不,没关系。您也可以将其删除,但如果构造函数被删除,则删除析构函数将不会执行任何其他操作。
第一个(已删除的构造函数)告诉您无法创建对象。第二个(删除的析构函数)告诉我们不可能销毁对象。
请注意,可以使用各种黑客“创建”和初始化对象,但在这些情况下,所有投注均已关闭,并且程序正在执行未定义的行为。
答案 2 :(得分:1)
要在此处添加其他答案,您可能需要将析构函数声明为已删除,而不是私有且未实现。这是因为,即使删除了private
构造函数,您仍然可以使用聚合初始化创建实例:
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
†调用析构函数,因此无法编译>
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
或显式调用析构函数将导致编译错误。如果我们方便地忘记了,那就没事了:
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
}
但是同时删除构造函数和析构函数可以防止这种情况:
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]:“如果删除了可能调用的析构函数,或者在调用的上下文中无法访问该程序,则程序格式错误。”