Board index » cppbuilder » auto_ptr to incomplete type
davjag2003
![]() CBuilder Developer |
auto_ptr to incomplete type2004-02-06 10:27:16 PM cppbuilder60 I believe I have found a solution to Borland Builder's problematic handling of auto_ptr members. Consider the following files (this can integrated into a VCL application): // in file MyClass.h class MyClass { public: ~MyClass(); }; // in file MyClass.cpp MyClass::~MyClass() { ShowMessage("MyClass dtor"); } // in file MyClassClient.h #include <memory> class MyClass; class MyClassClient { public: MyClassClient(); private: std::auto_ptr<MyClass>_myClass_ap; }; // in file MyClassClient.cpp #include "MyClass.h" MyClassClient::MyClassClient() : _myClass_ap(new MyClass) {} // now in the button click handler on some form void TForm1::Button1Click() { MyClassClient myClassClient; } If you've read this far it means you know that the call to ShowMessage("MyClass dtor") will never happen. The rules for cplusplus require that the destructor to MyClassClient be written AFTER the inclusion of MyClass.h So you rewrite MyClassClient.h as follows: #include <memory> class MyClass; class MyClassClient { public: MyClassClient(); ~MyClassClient(); // add an explicit dtor private: std::auto_ptr<MyClass>_myClass_ap; }; and then rewrite MyClassClient.cpp: #include "MyClass.h" MyClassClient::MyClassClient() : _myClass_ap(new MyClass) {} MyClassClient::~MyClassClient() { // this explicit dtor appears after MyClass has been declared in full. } If you had a nice bug-free compiler this would be all you had to do. But you're using Borland Builder so you have a bug and ShowMessage still doesn't get called. Assuming you're using the IDE, goto the Project menu and select Options. Now switch to the Compiler tab and uncheck Disable inline expansions. Rerun and, as if by magic, the Message box will appear! I haven't examined the reason for this but the dtor for auto_ptr is inline... Unfortunately all your inlines are now inline so step-debugging will be a bit strange. And if you like to use the "Debug" and "Release" shortcut buttons in Project Options you will have keep clearing this check box. Perhaps there's a #pragma to but around ~auto_ptr to always have it inlined? I haven't looked into this. If this is all to much hassle, replace all instances of auto_ptr with boost::shared_ptr (unless you really really can't afford the overhead) --- slight change of subject now --- There's something in the cplusplus standard along this lines of 'You can't instantiate an STL template class with an incomplete class type' I don't have a copy of the standard so I can't quote it accurately. I take this to mean you can't do this: class MyClass; std::vector<MyClass>vector; std::list<MyClass>list; This is fair enough as both vector and list need to know the size (and hence the complete type) of MyClass in order to create vectors and lists. Some people think you should apply this rule to auto_ptrs too: class MyClass; std::auto_ptr<MyClass>myClass_ap // some say this isn't allowed. Well, my own interpretation is that you're really just specifying what kind of pointer you want. As we all know a pointer (even a pointer to an incomplete type) is built-in and as such is never incomplete. So this is perfectly legal. I hope this is helpful to someone. |