Jump to content
  • Advertisement
Sign in to follow this  
Trillian

auto_ptr and incomplete types destructors

This topic is 4103 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello! Have a look at the following code which uses the pimpl idiom and auto_ptr :
// PtrTest.h
class PtrTest
{
public:
	PtrTest(void);
	~PtrTest(void);

private:
	class Impl;
	std::auto_ptr<Impl> mImpl;
};

// PtrTest.cpp
class PtrTest::Impl
{
public:
	Impl() { std::cout << "PtrTest::Impl constructed" << std::endl; }
	~Impl() { std::cout << "PtrTest::Impl destructed" << std::endl; }
};

PtrTest::PtrTest(void)
{
	std::cout << "PtrTest constructed" << std::endl;
	mImpl.reset(new Impl());
}

PtrTest::~PtrTest(void)
{
	std::cout << "PtrTest destructed" << std::endl;
}

// main.cpp
int main()
{
	std::cout << "Starting..." << std::endl;
	{
		PtrTest test;
	}
	std::cout << "Ending..." << std::endl;
	std::cin.get();
	std::cin.get();
	return 0;
}


Here's the output :
Starting...
PtrTest constructed
PtrTest::Impl constructed
PtrTest destructed
PtrTest::Impl destructed // !!!
Ending...
How can this work? When I coded my own auto_ptr, I got warnings saying "Deleting incomplete object (Impl), no destructors will be called". How can the auto_ptr delete a type that hasn't fully been defined yet? Is it a standard behavior or a MSVC extension? I checked it's code and I've seen "delete (_Ty *)_Myptr;", what is this delete syntax? Is it the global delete operator? While I'm asking questions about auto_ptr, what's the purpose of its operator=(auto_ptr_ref) if it doesnt handle syntax like "myAutoPtr = new PointedObject()" properly (without crashing)? Thanks for any clues, this really confuses me! [Edited by - Trillian on September 25, 2007 8:32:41 AM]

Share this post


Link to post
Share on other sites
Advertisement
Quote:
Original post by Trillian
How can this work? When I coded my own auto_ptr, I got warnings saying "Deleting incomplete object (Impl), no destructors will be called".

My guess is your test code for your hand-rolled auto_ptr was not the same as what you posted above.
Quote:
How can the auto_ptr delete a type that hasn't fully been defined yet?
Is it a standard behavior or a MSVC extension?

But the type has been fully defined at the point where the auto_ptr destructor is called in the above code. MSVC is (finally, in 2005 and later) fully standards conformant in this respect.

The above code is an idiomatic use of std::auto_ptr. I would encourage it.
Quote:
I checked it's code and I've seen "delete (_Ty *)_Myptr;", what is this delete syntax?
Is it the global delete operator?

It's not in the global namespace: the delete operator is a part of the language just like the new operator. Do not confuse them with overloadable namespace-level functions like ::operator delete(void*). The C-style cast is an artefact of history and whoever implemented the code you're looking at would be better off using C++ constructs, but that's mostly a matter of style at this point.
Quote:
While I'm asking questions about auto_ptr, what's the purpose of its operator=(auto_ptr_ref) if it doesnt handle syntax like "myAutoPtr = new PointedObject()" properly (without crashing)?

The assignment operator only allows assignment from another std::auto_ptr of a convertible type. Check the API of std::auto_ptr: are there any other constructors that you would want to avoidn implicit conversions for? How about the get() member function?

It's also a documentation aid. When you pass a raw pointer into an auto_ptr, ownership is passed, too. By forcing the explicit construction of the auto_ptr object it makes it abundantly clear that ownership is passed to the auto_ptr.

Share this post


Link to post
Share on other sites
Quote:
Original post by Trillian
While I'm asking questions about auto_ptr, what's the purpose of its operator=(auto_ptr_ref) if it doesnt handle syntax like "myAutoPtr = new PointedObject()" properly (without crashing)?


That shouldn't even compile. If it does compile, consider upgrading your compiler. In any case, if you want to assign a new object to an auto_ptr, you should use the reset() member function.

Share this post


Link to post
Share on other sites
Quote:
Original post by SiCrane
That shouldn't even compile. If it does compile, consider upgrading your compiler.


Upgrading Visual C++ 2005 Express Edition SP1? You're funny! =)

Anyways thanks for all the clarifications, I'll sure be using auto_ptr a lot more now that I know this!

Share this post


Link to post
Share on other sites
How about if the pimpl'ed class' destructor was inlined in the header, or if I used the default destructor? Then I'd get the "deleting incomplete object, no destructors will be called", wouldn't I?

That would explain why I got the error using my own auto_ptr : not because of the class' implementation itself but because of the destructor of the class in which it was used!

Does that make sense? I think it does!

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!