Reputation: 531
Is it considered bad manners/bad practice to explicitly place object members on the heap (via new)? I would think you might want to allow the client to choose the memory region to instantiate the object. I know there might be a situation where heap members might be acceptable. If you know a situation could you describe it please?
Upvotes: 9
Views: 2822
Reputation: 59837
If you have a class that's designed for copy semantics and you're allocating/deallocating a bunch of memory unnecessarily, I could see this being bad practice. In general, though, it's not. There are a lot of classes that can make use of heap storage. Just make sure you're free of memory leaks (deallocate things in the destructor, reference count, etc.) and you're fine.
If you want more flexibility, consider letting your user specify an Allocator. I'll explain.
Certain classes, e.g. std::vector
, string, map, etc. need heap storage for the data structures they represent. It's not considered bad manners; when you have an automatically allocated vector
, the user is expected to know that a buffer is allocated when the vector
constructor gets called:
void foo() {
// user of vector knows a buffer that can hold at least 10 ints
// gets allocated here.
std::vector<int> foo(10);
}
Likewise, for std::string
, you know there's an internal, heap-allocated char*
. Whether there's one per string
instance is usually up to the STL implementation; often times they're reference counted.
However, for nearly all of the STL classes, users do have a choice of where things are put, in that they can specify an allocator. vector
is defined kind of like this:
template <typename T, typename Alloc = DefaultAllocator<T> >
class vector {
// etc.
};
Internally, vector
uses Alloc
(which defaults to whatever the default allocator is for T) to allocate the buffer and other heap storage it may need. If users doesn't like the default allocation strategy, they can specify one of their own:
vector<int, MyCustomAllocator> foo(10);
Now when the constructor allocates, it will use a MyCustomAllocator
instead of the default. Here are some details on writing your own STL allocator.
If you're worried that it might be "bad manners" to use the heap for certain storage in your class, you might want to consider giving users of your class an option like this so that they can specify how things are to be allocated if your default strategy doesn't fit their needs.
Upvotes: 13
Reputation: 46044
I don't consider it bad practice at all. There are all sorts of reasons why you might want to explicitly allocate a member variable via new. Here are a few off the top of my head.
On the flip side, if your users create a lot of instances of your class for use on the stack, it would be advantageous to use objects instead of pointers for your member variables simply because heap allocations/deallocations are slow by comparison. It's more efficient to avoid the heap in this case, taking into account the first bullet above of course.
Upvotes: 10
Reputation: 8805
Where the class puts its members is less important than that the management of them is contained within the class; i.e. clients and subclasses shouldn't have to worry about the object's member variable.
The simplest way to do this would be to make them stack variables. But in some cases, such as if your class has a dynamic data structure like a linked list, it doesn't make sense.
But if you make sure your objects clean up after themeselves, that should be fine for most applications.
Upvotes: 1
Reputation: 3180
hmm, I don't really understand your question.
If you have a class :
class MyOtherClass;
class MyClass
{
MyOtherClass* m_pStruct;
};
Then, the client of MyClass does not have a real choice on how m_pStruct will be allocated.
But it will be the client's decision on how the class MyClass will itself be allocated, either on the stack or on the heap:
MyClass* pMyClass = new MyClass;
or
MyClass myClass;
Upvotes: 0