On 28.12.17 07.42, 唐彬 wrote:
> class Smart_Ptr {
> public:
> Smart_Ptr(int *_p): ptr(new U_Ptr(_p)) {
> cout << "Smart_Ptr constructor is called !" << endl;
> }
First of all the copy constructor is missing. So ->use is not
incremented in this case.
This will decrement ->use multiple times on destruction. On the first
invocation the underlying object is destroyed. Any further access is
after the memory has been released, i.e. UB.
> void test() {
> int a = 8;
> Smart_Ptr obj(&a);
Secondly you taking the address of an object on the stack here and pass
it to a smart pointer that takes the ownership. The resulting call to
delete will sadly fail because the object is owned by the stack rather
than the heap. Again UB.
> cout << "int val of obj a is " << obj.get_int() << endl;
> return ;
> }
Here it crashes because the destructor invokes delete &a;
BTW. it is amazingly complex to write real safe reference counted smart
pointers, especially if multiple threads come into play. And it's more
complex to write a smart pointer which is still pretty fast. Have a look
at the implementation of std::shared_ptr to get an impression of it.
And it is even more complex to write a reference counted smart pointer
that provides strong thread safety, i.e. get access to a valid object
from a global smart pointer instance that changes asynchronously. Not
even std::shared_ptr supports this pattern.
Marcel