*
ankitks@yahoo.com:
Quote:
Quote:
>If destructor code is to be "reused", then most likely the class has a
>default "empty" state established by default construction.
>>
>In that case one nice technique is to implement a swap() function, which
>should never throw but just swap the contents of two objects, and then write
>>
> void Note::clear()
> {
> Note().swap( *this );
> }
>>
>Voilą, the destructor code has been reused, completely safely!
>
Sorry, I am little lost. Can you provide some example.
See above. ;-)
Another example is the idiom for /really/ clearing a std::string or
std::vector, like
template< typename T >
void reallyClear( std::vector<T>& v )
{
std::vector<T>().swap( v );
}
which in practice releases the buffer memory held by v.
And a third example is the idiom for producing a large collection in an
exception safe manner, by clearing the caller's object if and only if
the code succeeds in creating the large collection:
void getManyNumbers( std::vector<int>& result )
{
std::vector<intnumbers;
for( int i = 0; i < 10000; ++i )
{
numbers.push_back( i );
}
// If execution reaches this point all is OK.
// Otherwise, the callers 'result' is unaffected.
numbers.swap( result ); // Won't ever throw.
}
inline std::vector<intmanyNumbers()
{
std::vector<intresult;
getManyNumbers( result );
return result; // Rely on compiler's RVO optimization.
}
Quote:
So you are
saying that we can do now is
Note::~Note()
{
clear();
}
No. The destructor must do whatever it needs to do to clean up.
clear() uses the destructor logic, by means of C++'s automatic
destructor calls (a temporary object is created and destroyed), and not
the other way around.
Quote:
isn't this will do recursive calling of swap.
Yes.
Quote:
Quote:
>Plus, an assignment operator can now reuse the copy constructor (if the
>class has a copy constructor):
>>
> Note& Note::operator=( Note const& other )
> {
> Note( other ).swap( *this );
> return *this;
> }
>>
>Plus, that swap operation might come in very handy for other things.
>>
>
I can see, we are creating new object of note type, with copy
constructor for other. Now we are swaping it contents. So now *this
look like other. But how is this exception safe?
The constructor call will either succeed (no exception), or fail with an
exception in which case there's no partially assigned invalid-state
object left behind: there's nothing left behind. If the constructor
call succeeds, swap is called, but is guaranteed to not throw. We say
that swap offers the "no-throw exception guarantee".
From this perspective swap is a more fundamental operation than assignment.
Since most or all assignable standard library classes offer such a swap
operation (I haven't checked whether absolutely all do), this is a very
useful idiom -- one might say that those who put in place all those
swap operations in the standard library, knew what they were about...
In the other direction, I recently had the displeasure of working on a
project where the copy constructor generally was implemented in terms of
the assignment operator, which in turn was implemented in terms of an
Assign() function, which was implemented in terms of MemberWiseCopy,
which should copy only the data members added in the class it was
defined, and this was done for all objects, in particular for those that
should really not be copyable (no distinction was made).
One might say that the architect there did not know what he was about.
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?