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 ge开发者_Go百科t 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?
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 delete
d 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.
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.
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.
精彩评论