What is the best practice in C++ to declare objects within classes?
I'm working on a 开发者_如何学运维class library in VC++ that shall have ref classes and some native code. Now, I need to use five native objects from an external framework. those objects must be declared on the heap NOT on the stack. I want encapsulate those objects in some sort of a structure knowing that constructors need to be called.
Thank you.
I'm not sure I know exactly what you're asking. Constructors always need to be called on objects whether they are on the heap or the stack. If you meant that you want something to automatically call destructors for heap allocated memory, then you can use either std::auto_ptr or boost::shared_ptr. Note that these are not equivalent so read the documentation! Auto pointers cannot be used in standard containers as they do not have the copy semantics necessary, while boost::shared_ptr can as it counts references as it copies.
To answer your more general question of declaration best-practices, you want to only fully declare objects that you need to and forward declare when you can. For example, if you have a class like:
// In X.h
class MyConfig;
class X
{
X(const MyConfig &config);
private:
const MyConfig &config;
};
// In X.cpp
#include "MyConfig.h"
X::X(const MyConfig &config) : config(config)
{
}
Here you do not need to full declaration contained in MyConfig.h within the X.h header file. You can do this b/c you do not need to know the size of the MyConfig object to construct class X as it only contains a reference which is the same size regardless of what the underlying object is. Doing this will help with dependencies and will also reduce compile times.
If on the other hand the private member config was changed to const MyConfig x;
then you would have to include the MyConfig.h header in X.h because to construct class X requires knowledge of how much memory to allocate to store a MyConfig object.
Well, for each unmanaged class X, declare a ref class XWrapper that stores the unmanaged pointer to X privately, new's in constructor, and delete's in destructor. Why not?
You should wrap a shared_ptr
like this:
template <class T>
class my_object_wrapper
{
boost::shared_ptr<T> ptr; // or std::tr1::shared_ptr<T> if available
public:
my_object_wrapper()
: ptr(new T)
{
}
boost::shared_ptr<T> ptr() const { return ptr; }
}
You could also use the pheonix approach:
template <class T>
class my_object_wrapper
{
boost::shared_ptr<T> ptr; // or std::tr1::shared_ptr<T> if available
public:
my_object_wrapper()
{
}
boost::shared_ptr<T> ptr()
{
if (ptr == null)
ptr = new T;
return ptr;
}
}
精彩评论