The language does not support what you are trying to do using raw pointers. If you have the option of using std::shared_ptr
, you can get what you are looking for.
Response to OP's comment
The objective of using delete
is to terminate the life of an object.
If an object is shared by multiple clients, by holding a pointer to the object, independent of one another, you have to make a policy decision on how to manage the life of the object.
Don't allow the life of the object to end until no client has a pointer to it. This is the policy implemented by shared_ptr
.
Allow the life of the object to end when the first client wants to end it while making sure that the remaining clients know that the life of the object has ended.
It appears that you want to implement the second policy.
Calling delete
directly on the pointer will not work to implement that policy since the language does not support it.
There are no smart pointer classes in the standard library, that I know of, that supports that policy. However, it's not that hard to implement one.
Here's a demonstrative implementation of such a class.
#include <iostream>
#include <cassert>
template <typename T>
struct my_shared_ptr
{
my_shared_ptr(T* ptr) : dataPtr_(new data(ptr))
{
}
my_shared_ptr(my_shared_ptr const& copy) : dataPtr_(copy.dataPtr_)
{
++(dataPtr_->use_count_);
}
~my_shared_ptr()
{
delete dataPtr_->ptr_;
--(dataPtr_->use_count_);
if ( dataPtr_->use_count_ == 0 )
{
delete dataPtr_;
}
else
{
dataPtr_->ptr_ = nullptr;
}
}
// Overloaded operator functions to use objects of
// the class as pointers.
T& operator*()
{
assert(dataPtr_->ptr_ != nullptr);
return *(dataPtr_->ptr_);
}
const T& operator*() const
{
assert(dataPtr_->ptr_ != nullptr);
return *(dataPtr_->ptr_);
}
T* operator->()
{
assert(dataPtr_->ptr_ != nullptr);
return dataPtr_->ptr_;
}
const T* operator->() const
{
assert(dataPtr_->ptr_ != nullptr);
return dataPtr_->ptr_;
}
struct data
{
data(T* ptr) : ptr_(ptr), use_count_(1) {}
T* ptr_;
size_t use_count_;
};
data* dataPtr_;
};
int main()
{
my_shared_ptr<int> ptr1{new int(10)};
std::cout << *ptr1 << std::endl;
my_shared_ptr<int> ptr2{ptr1};
std::cout << *ptr2 << std::endl;
{
my_shared_ptr<int> ptr3{ptr1};
std::cout << *ptr3 << std::endl;
}
// Problem. The int got deleted when ptr3's life ended
// in the above block.
std::cout << *ptr1 << std::endl;
return 1;
}
Output of the above program built with g++
:
10
10
10
socc: socc.cc:35: T& my_shared_ptr<T>::operator*() [with T = int]: Assertion `dataPtr_->ptr_ != nullptr' failed.
Aborted
Please note that you will need to implement at least the copy assignment operator to make the class confirm to The Rule of Three. You will need further improvements to deal with pointers to base classes and derived classes.