Michael
Michael

Reputation: 187

Do I need to nullify a member variable in the destructor?

Why one would want to explicitly clear the a vector member variable (of on in a dtor (please see the code below). what are the benefits of clearing the vector, even though it will be destroyed just after the last line of dtor code will get executed?

class A
{
~A()
{
   values.clear();
}

private: 
  std::vector < double > values_;
};

similar question about a the following code:

class B
{
~B()
{
   if (NULL != p)
   {
       delete p_;
       p_ = NULL;
   }
}

private: 
  A * p_;
};

Since there is no way the dtor will get called twice, why to nullify p_ then?

Upvotes: 8

Views: 1838

Answers (3)

AnT stands with Russia
AnT stands with Russia

Reputation: 320631

In your second example there's no reason to set p_ to null whatsoever, specifically because it is done in the destructor, meaning that the lifetime of p_ will end immediately after that.

Moreover, there's no point in comparing p_ to null before calling delete, since delete expression performs this check internally. In your specific artificial example, the destructor should simply contain delete p_ and noting else. No if, no setting p_ to null.

Upvotes: 2

Steve Rowe
Steve Rowe

Reputation: 19413

In the case of p_, there is no need to set it equal to null in the destructor, but it can be a useful defensive mechanism. Imagine a case where you have a bug and something still holds a pointer to a B object after it has been deleted:

If it trys to delete the B object, p_ being null will cause that second delete to be innocuous rather than a heap corruptor.

If it trys to call a method on the B object, p_ being null will cause a crash immediately. If p_ is still the old value, the results are undefined and it may be hard to track down the cause of the resulting crash.

Upvotes: 0

James McNellis
James McNellis

Reputation: 355157

In class A, there is absolutely no reason to .clear() the vector-type member variable in the destructor. The vector destructor will .clear() the vector when it is called.

In class B, the cleanup code can simply be written as:

delete p_;

There is no need to test whether p_ != NULL first because delete NULL; is defined to be a no-op. There is also no need to set p_ = NULL after you've deleted it because p_ can no longer be legitimately accessed after the object of which it is a member is destroyed.

That said, you should rarely need to use delete in C++ code. You should prefer to use Scope-Bound Resource Management (SBRM, also called Resource Acquisition Is Initialization) to manage resource lifetimes automatically.

In this case, you could use a smart pointer. boost::scoped_ptr and std::unique_ptr (from C++0x) are both good choices. Neither of them should have any overhead compared to using a raw pointer. In addition, they both suppress generation of the implicitly declared copy constructor and copy assignment operator, which is usually what you want when you have a member variable that is a pointer to a dynamically allocated object.

Upvotes: 12

Related Questions