开发者

Design of pointer container template

I would like to write a "versatile" class representing the general container storing pointers. Should I use public inheritance or containment?

template <class T>
class List : public std::vector <T *>
{
//...
}
开发者_如何学Python

Or

template <class T>
class List
{
private:
   std::vector <T *> items;
//...
}

May some problems occur with abstract classes (i.e. virtual destructor)?

If neither proposal is appropriate, what design should I follow (and could you include a short example)?


This is already done for you with Boost's pointer containers.

I do not like boost so I would like to use only C++ 0x00 standard :-).
  — Ian (comment)

If you still want to re-invent these classes, look at the design decisions they made. In particular, they don't inherit from other containers as your first code does.

In fact, just copy the code right out from Boost. This is a header-only library and should be straight-forward (i.e. few implementation-specific workarounds). Boost's license is very liberal, not even requiring you to mention Boost when distributing compiled programs.


How about:

typedef std::vector<boost::shared_ptr<T> > List;

That is, I think it's better to use a resource managing pointer within regular container classes than to reinvent each of the container classes to add resource management capability.


private inheritance is a common tactic for creating classes that are implemented in terms of another. Code that uses the class can't tell that the derived class is derived from a private base, so you won't end up in the sorts of situations that might ordinarily require a virtual destructor.

Use using to import members from the private base to the derived class. For example:

template<class T>
class List:
private std::vector<T>
{
public:
    using std::vector<T>::operator[];
    using std::vector<T>::size;
};

This is a bit crude, but it gives you some flexibility. You can start out by using private inheritance, and this saves you some typing compared to writing forwarding functions, but you can still write alternative implementations long-hand as required. And then, if/when this becomes inappropriate, you can change the implementation style -- perhaps have a vector as a member, for example, or maybe do everything by hand -- safe in the knowledge that client code won't need to change.

This is ideal for situations where you're pretty sure you'll eventually need a non-standard type of container, but have an existing container type that mostly fits the bill for now. And it's a better medium-term solution than a typedef, because there's no risk of client code accidentally (or on purpose...) using the two types interchangeably.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜