It's definitely "not right", in the sense that it's giving me the creeps.
Since test
has no user-declared constructors, I think it could work provided that the instance of test
isn't value-initialized (which would clear the pointer). And provided that you write the corresponding operator delete
.
It's clearly a silly example, though - user interaction inside an overloaded operator new
? And what if an instance of test
is created on the stack? Or copied? Or created with test *tp = new test();
in C++03? Or placement new? Hardly user-friendly.
It's constructors which must be used to establish class invariants (such as "I have an array to use"), because that's the only way to cover all those cases. So allocating an array like that is the kind of thing that should be done in a constructor, not in operator new
. Or better yet, use a vector
instead.
As far as the standard is concerned - I think that since the class is non-POD the implementation is allowed to scribble all over the data in between calling operator new
and returning it to the user, so this is not guaranteed to work even when used carefully. I'm not entirely sure, though. Conceivably your professor has run it (perhaps many years ago when he first wrote the course), and if so it worked on his machine. There's no obvious reason why an implementation would want to do anything to the memory in the specific case of this class.
I believe that is "wrong" because he
access the object before the
constructor.
I think you're correct on this point too - casting the pointer returned from malloc
to test*
and accessing members is UB, since the class test
is non-POD (because it has private non-static data members) and the memory does not contain a constructed instance of the class. Again, though, there's no reason I can immediately think of why an implementation would want to do anything that stops it working, so I'm not surprised if in practice it stores the intended value in the intended location on my machine.