Reputation: 11773
I give the following example to illustrate my question. Suppose Abc
is a class that will use another class (Def
). Assume Def
is a large class with many class members (expensive for copying), it make more sense to let the pointer to a Def object be part of Abc class. Then when implementing Abc
class function do1
, it can refers to Def object via its pointer pDef
.
class Abc
{
public:
Abc(Def &def)
{
pDef = &def;
}
~Abc()
{
}
void do1();
private:
Def *pDef;
}
However, if I implement class Abc in this way, I will have the risk that the Def
pointer might be invalid. Any ideas on improving this class design? One idea I have is to use share pointer:
class Abc
{
public:
Abc(boost::shared_ptr<Def> def)
{
pDef = def;
}
~Abc()
{
}
void do1();
private:
boost::shared_ptr<Def> pDef;
}
EDIT: I want to make it clear that my main purpose is to avoid the expensive copy operation when constructing class Abc
. For me using the shared pointer and James Adkison's solution (accepted answer) can both solve the problem. But the effect on the expensive Def
object may be different. Using shared pointer will keep many copies of the object while using James Adkison's solution will only keep one copy of Def
object.
Upvotes: 2
Views: 400
Reputation: 9602
Assume Def is a large class with many class members
I assume this means that it is expensive to copy the Def
class. However, with C++11 you could implement move semantics for Def
and keep the Abc
implementation simple and efficient.
Note: This answer is based on the assumption that the only reason the question uses any pointers (smart or otherwise) is as a way to avoid expensive copies.
class Def
{
public:
Def() {}
Def(const Def& other) { /* ... */ } // Copy constructor even though it's expensive
Def(Def&& other) { /* ... */ } // Move constructor for efficiency
Def& operator=(const Def& other) { /* ... */ } // Copy assignment
Def& operator=(Def&& other) { /* ... */ } // Move assignment
};
Now the Def
class supports copy semantics, even though copy the class may be expensive. However, it also supports move semantics to allow efficient usage when a copy isn't required.
class Abc
{
public:
Abc() {}
Abc(const Def& def) : mDef(def) {} // Perform an expensive copy
Abc(Def&& def) : mDef(std::move(def)) {} // Perform a move
// Implement any other member functions which could accept Def
// via copy or move
private:
Def mDef;
};
I would only advocate using std::shared_ptr
if the use case is actually to support shared ownership semantics.
Upvotes: 3
Reputation: 3361
Why use a pointer if you can use a reference?
class Abc
{
public:
Abc(Def &def) : pDef(def)
{
}
void do1();
private:
Def& pDef;
}
You aren't passing ownership, so there's no need for pointers.
Think of a reference like a pointer that can never be null.
Upvotes: 1
Reputation: 118445
This is what std::shared_ptr
is for. If you use std::shared_ptr
, the pointer will always be valid (as long as you follow all the very simple rules).
Upvotes: 0