Reputation: 407
My question is this: after deleting a constructor is there any way to initialize a class? For example
class A{
public:
A() = delete;
int a = 42;
int fun(){
a += 1;
return a;
}
};
Now it should not be possible to use this class. For example you cannot:
A* instance = (A*)malloc(sizeof(A));
instance->fun(); //segfault
and
A instance; //compile error undefined function
Assuming for some strange reason you actually wanted to use the class with the constructor deleted is there a way that you could do it? That is without doing something like overriding the constructor.
I know this is a strange question, but I am interested in knowing if someone has a (perhaps obscure) way of doing this. Thanks!
Upvotes: 3
Views: 131
Reputation:
The reason this is allowed is that calling malloc
is not equivalent to calling new
. malloc
merely allocates memory and returns where it begins; new
allocates and constructs an object. Just directly creating an A
, as in A instance;
, runs the constructor as well - so it expects it to be there.
As such, it is not an error as you never actually construct any A
object. You allocate uninitialized memory, cast the pointer to A*
, and then call it. This is valid because the language and the compiler don't care (or likely know) where you got that memory. All it knows is that at runtime, instance
contains valid allocated memory; if that were not the case, it might segfault (it also might not, but would still probably be bad).
What happens when you actually run this is that fun()
will access uninitialized memory as if it were an A
; as such, int a
will be something, but probably not 42.
It's not required that a pointer be to a constructable class. For example, you can cast an actual class pointer to one of its non-constructable interface classes and still access it. Effectively, the same methodology that allows that allows this.
Upvotes: 3
Reputation: 141554
If the class is an aggregate you can create one using aggregate initialization, which does not call a constructor of A
. For example:
A a = { 1 };
In C++11 your class was not an aggregate because of the presence of the = 42
. So in C++11 your class is unusable.
But in C++14 this was changed, and = 42
does not prevent the class being an aggregate, so it is usable again.
Upvotes: 4