Consider the following class.
class mapping_开发者_StackOverflow社区items
{
public:
mapping_items(){}
void add(const mapping_item* item) {
items_.push_back( item );
}
size_t count() const{
return items_.size();
}
const mapping_item& find(const std::string& pattern){
const mapping_item* item = // iterate vector and find item;
return *item;
}
private:
mapping_items(const mapping_items&); // not allowed
mapping_items& operator=(const mapping_items&); // not allowed
std::vector<const mapping_item*> items_;
};
C++ FAQ says,
Use references when you can, and pointers when you have to.
So in the above example, should I return const mapping_item&
or const mapping_item*
?
The reason why I chose mapping_item&
is because there will be always a default return value available. I will never have null returns. So a reference makes it clear that it can't have nulls. Is this the correct design?
There is a problem - what happens if your find() function fails? If this is expected never to happen, you are OK returning a reference (and raise an exception if it happens despite the fact it shouldn't). If on the other hand it may happen (e.g. looking up a name in an address book), you should consider returning a pointer, as a pointer can be NULL, indicating the find failed.
This is seems like an appropriate design choice to me - like the C++ FAQ states - uses references when you can. IMO, unnecessary use of pointers just seems to make code harder to understand.
Yes, it's the correct design. Clients can rely on values being non-null.
On a related note, some other class is responsible for managing the lifetime of mapping_item's?
Pointers and ownership easily introduces memory leaks or worse. You might want to consider whether you actually need to store pointers, or if you can get away with copying mapping_item's instead, to avoid memory leaks. However, pointers are necessary if you need to manage subclassed mapping_item's. Pointers are advisable if instances are large or need to be shared.
If you really need pointers, consider using boost::shared_ptr<> rather than raw pointers, both inside your class and as parameter types to e.g. the add() function.
Some people say, and I agree,
use pointers if value can be
NULL
and references otherwise
As to your example, I'd probably go for return const mapping_item;
, so by value, to avoid having a reference to a temporary, and hope for my compiler to optimize copying away.
精彩评论