C++ is so amazing that when you don't define a copy constructor, move constructor, copy assignment and move assignment for a class, the compiler will have to define them for you (the Standard says so). Of course you can delete them via:
func() = delete;
So for example, if you want to delete the implicit copy constructor in your example you would declare:
test(const test&) = delete;
and as you can see your code won't no longer compile.
The behavior of the implicit copy constructor is the one you would expect: it will copy construct each member of the class to the the other object. In this case it will copy construct the pointer value (not the pointed value), effectively make the two object share the same pointer.
Now, your program is leaking memory right? You have called new
but no delete
. Let's say you want to clean your resources up by inserting:
delete ptr;
in the destructor (it's a simplified version, of course you would need to define at least a proper move assignment and move constructor). You know what will happen? A nice and beautiful runtime error, telling you that the pointer you are trying to free has not been allocated. The reason why that is, is that both your objects (t1
and t2
) destructors a will be called and they will both delete the same pointer. The first correctly and the second erroneously.
For this reason a Rule of three (now Rule of Five) has been established in the C++ community. But you know what? There's even a better rule which is called Rule of Zero. To sums it up (but you should really read about it) it says: don't do RAII yourself. I'd suggest you to follow the latter.
Now, let's discuss a little a bit of new
. I'm sure you know this, but I'm here to prevent future damages: you don't need to use new
at all in C++. Not anymore, in most cases.
Most of the things pointers once did (optional parameter, pass array by pointer, copyable reference, etc..) has now been "deprecated" (not in the literal sense: they are still there) in favor of sexier approaches (namely boost:optional
/std::optional
, std::array
/std::vector
, std::reference_wrapper
). And even when all those fails to give you what you need, you can still use std::shared_ptr
and std::unique_ptr
.
So, please, don't use naked new
pointers. Thanks.