Reputation: 978
Let's say I have a class that allocates some arbitrary member data. There are two common ways that I have seen used (I know that there are others):
class A
{
public:
A();
~A();
//Accessors...
private:
B *mB;
}
A::A()
{
mB = new B();
}
A::~A()
{
delete B;
}
Versus...
class A
{
public:
//Accessors...
private:
B mB;
}
Assume that A itself will be allocated on the heap by consumer code.
In the general case, which method is preferred? I realize that specific situations really encourage one way or the other, but in absence of those demands, is one way preferred? What are the tradeoffs?
Upvotes: 3
Views: 211
Reputation: 299760
It depends, mainly, on what you are looking for.
For simplicity's sake: don't use a pointer. Therefore the second choice.
It's easier to manage (no need to worry about memory management, deep copying, deep constness, etc...).
However you might need dynamically allocated attributes sometimes:
Even in this case though, hand over the responsibility to a smart manager (smart pointer, dedicated pimpl class, etc...)
Upvotes: 0
Reputation: 99094
It depends.
In general, If a B is large and unwieldy then it's easier to pass around a pointer to the B than the B itself. So if the B will often be disassociated from the A (f'rinstance if your A's swap B's) then the first way is better.
Using a pointer can also reduce dependencies. If you do it right, A.hh
can get by without specifiying what a B is or does (i.e. A.h
need not #include "B.hh"
) so that things that depend on A.hh
won't necessarily depend on B.hh
.
The price of using pointers is an extra layer of machinery and the dangers of things like lost objects, double-deletion and the dereferencing of uninitialized pointers, so it shouldn't be used unless it actually gives a benefit in your situation. Some people fall in love with pointer techniques and use them everywhere; if they want to improve as programmers they have to grow out of it.
Upvotes: 4
Reputation: 96233
In general, prefer direct composition (the second choice). In that case there is no chance of leaking memory and the object is fully located in a contiguous memory block, allowing better cache locality.
You might use the first option if you're implementing a PIMPL, or you have a need to use one of several possible class types (via inheritance). In that case definitely use a smart pointer (boost::shared_ptr
for example) to manage the memory for you.
Upvotes: 0
Reputation: 754565
The second is the preferred route. Do not use new / delete unless you specifically need a variable to be on the heap or have a lifetime longer than it's container. C++ value types are easier to manage and have less error cases to worry about IMHO
Upvotes: 9