C++11 Destructor = delete
~A() = delete;
is redundant, because since you cannot create an object, there is no point of worrying about destructor.
In fact with your code even there is no need of A() = delete;
, because all the class members are static
.
As Luchian rightly mentioned in the comment, such class
are better be declared as a namespace
. Underlying data can be made extern
/ static
depending on the requirement.
(Note: In C++20, deleting the constructor of an aggregate now makes the type impossible to construct, so no more unexpected behavior)
To add to the other answers here, you might want to declare the destructor as deleted instead of as private and not implemented. This is because, even with a private
deleted constructor, you can still use aggregate initialization to create an instance:
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
}
However, if you declare the destructor as deleted, neither default construction or aggregate initialization will work -- it fails to compile because the compiler cannot invoke the destructor for 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
}
Since you've already declared your destructor as private and not implemented, all the other stuff is redundant. C++11 makes it easier in that you don't need private
, just = delete
on the destructor. Explicitly declaring the destructor as deleted is preferable because it communicates to other programmers that you never intended to implement it. The way you have it, some programmer may initially think you just forgot to include the implementation.
You will want to declare both the default constructor and the destructor as deleted in order to protect against dynamic memory allocation (via new
or placement new) because we otherwise won't get a compilation error because it's now on us to call delete
or explicitly invoke the destructor. And if we conveniently forget, then things are fine:
Demo
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
}
Placement new demo
But deleting both the constructor and destructor prevents this:
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
}
†refer to [class.dtor]: "A program is ill-formed if a destructor that is potentially invoked is deleted or not accessible from the context of the invocation."