Travis Vitek wrote:
> On Apr 25, 9:53 am, rwf_20 <rfr...@[EMAIL PROTECTED]
> wrote:
>> myClass::myClass() : m_pimpl(std::auto_ptr<myStruct>(new myStruct()))
>> { }
>
> You should be able to simplify that to
>
> myClass::myClass() : m_pimpl(new myStruct())
> { }
>
>> This compiles just fine, until I try to use myClass elsewhere. At
>> this point, I get warnings like:
>>
>> "deletion of pointer to incomplete type 'myStruct'; no destructor
>> called"
>>
>> I guess I understand why this happens, and it's fixed by declaring a
>> destructor for myClass and defining it in the .cpp file. It just irks
>> me that I need to define a blank destructor (the same thing the
>> compiler should generate) to make this work.
>
> Because the C++ standard allows pointers to incomplete class types to
> be deleted but if the class has a non-trivial destructor or a class
> operator delete the behavior is undefined.
>
> The problem is that if you don't define the destructor in the cpp, the
> compilers implicit definition will be used. This implicit definition
> will be as if it were declared inline in the header file. The
> destructor for myClass will call the destructor for the auto_ptr,
> which will call delete on a pointer to the incomplete type
> myClass::myStruct. The result is undefined behavior.
>
> If you define the destructor of myClass after the definition of the
> nested class myClass::myStruct, then everything will work as expected
> and you'll avoid the warning that you are seeing.
>
>> Googling this issue, I
>> findhttp://www.gotw.ca/publications/using_auto_ptr_effectively.htm,
>> in which Mr. Sutter demonstrates this same code and adds the comment:
>>
>> "In fact, if there's no other reason for explicitly writing a
>> destructor, we don't need to bother with a custom destructor at all
>> any more."
>>
>
> This is one of the 'other reasons' he is talking about. It is a
> special case.
>
In fact, he's talking of "no other reasons" / "don't need to bother with
a custom destructor at all" which apparently is plain wrong in this
situation -- There is (at least) one reason to write the dtor, namely
that otherwise the pimpl would not work, as it's dtor would never be
called.
Just goes to show that you should never believe something unless you've
tried it yourself :-)
Supposedly boost::shared_ptr does avoid the problems of auto_ptr, as
mentioned here:
http://www.eggheadcafe.com/forumarchives/vcstl/Dec2005/post24687900.asp
"The const auto_ptr Idiom" also described in Sutter's article might be
interesting to apply to the pimpl -- it would avoid accidentally copying
or otherwise invalidating the pimpl ...
class myClass {
public:
myClass();
~myClass();
private:
struct myStruct;
const std::auto_ptr<myStruct> m_pimpl; // note const
};
br,
Martin
--
[ See http://www.gotw.ca/resources/clcm.htm
for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


|