auto_ptr

Started by
11 comments, last by MaulingMonkey 18 years, 4 months ago
Quote:Original post by Anonymous Poster
Quote:Original post by Bregma
This has the advantage that you don't need to write your own destructor to delete m_x, the default destructor will do the right thing, ...


No it won't, in this case.


It won't even compile without X defined ("new X" is invalid at that point in this translation unit otherwise)

Quote:It will ONLY be deleted properly if the class has a non-default destructor.


Not true - for both MSVC++ 2k5 and GCC 3.4.2, if X is defined in the same translation unit (even if forward declared originally as above) ~X is properly called.

The issue you're thinking of occurs when:

1) You destroy the containing object (of type C) in a translation unit T
2) The containing object (of type C) uses a default destructor.
3) You never define the contained type (X) in translation unit T.

#include <memory>#include <iostream>class X;class C{private:  std::auto_ptr< X > m_x;public:	C(); //deffered until X defined	//default destructor};int main () {	C c;} //result: ~X when c goes out of scope.class X { public: ~X() { std::cout << "~X" << std::endl; } };C::C() : m_x( new X ) {}


Any compiler claiming to be modern should display a warning when invoking such behavior. Both MSVC++ 2k5 and GCC 3.4.2 do at least, with default settings.

There is an alternative scenario:

1) You destroy the containing object (of type C).
2) The containing object (of type C) uses a non-default destructor, defined in translation unit T.
3) You never define the contained type (X) in translation unit T.

MSVC++ 2k5 dosn't seem to catch this one, oddly. GCC 3.4.2 generates warnings.

// c.hpp ////////////////#include <memory>class X;class C{private:  std::auto_ptr< X > m_x;public:	C(); //deffered until X defined	~C();};// x.cpp ////////////////#include <iostream>#include "c.hpp"class X { public: ~X() { std::cout << "~X" << std::endl; } };C::C() : m_x( new X ) {} //here because we need X defined to new it.// c.cpp ////////////////#include "c.hpp"C::~C() {} //here because we need X not defined to show the problem// main.cpp /////////////#include "c.hpp"int main () {	C c;} //result: no ~X


Both these scenarios have 1 thing in common: X's destructor is not defined in the same translation as C's, whether C's is compiler generated ("default") or explicit.
Advertisement
Quote:Original post by MaulingMonkey
...Not true...


Knee-jerk reaction. Didn't see the ctor defined in the definition, and thought it was a header...

Merry Christmas!
David
Quote:Original post by Anonymous Poster
Quote:Original post by MaulingMonkey
...Not true...


Knee-jerk reaction. Didn't see the ctor defined in the definition, and thought it was a header...


It could be... a sane reason for a forward decleration, followed by an actual definition later on, within a header, would be a circular dependancy (with f being implicitly inline).

I just hate not-quite-truths, so I felt the need to clarify. But it was good to bring up.

This topic is closed to new replies.

Advertisement