好吧,这真的很难承认,但我确实有一个强烈的诱惑,从std::vector继承。

I need about 10 customized algorithms for vector and I want them to be directly members of the vector. But naturally I want also to have the rest of std::vector's interface. Well, my first idea, as a law-abiding citizen, was to have an std::vector member in MyVector class. But then I would have to manually reprovide all of the std::vector's interface. Too much to type. Next, I thought about private inheritance, so that instead of reproviding methods I would write a bunch of using std::vector::member's in the public section. This is tedious too actually.

在这里,我真的认为我可以简单地从std::vector公开继承,但在文档中提供了一个警告,该类不应该多态地使用。我认为大多数开发人员都有足够的能力来理解这无论如何都不应该多态地使用。

我的决定是绝对不合理的吗?如果有,为什么?你能提供一个替代方案,这将有额外的成员实际上成员,但不会涉及重新键入所有矢量的接口?我很怀疑,但如果你能做到,我会很开心的。

而且,除了有些白痴能写出这样的东西

std::vector<int>* p  = new MyVector

使用MyVector还有其他现实的危险吗?通过说现实,我放弃了一些东西,比如想象一个函数,它接受一个指向向量的指针…

我已经陈述了我的观点。我有罪。现在就看你是否原谅我了:)


当前回答

There is no reason to inherit from std::vector unless one wants to make a class that works differently than std::vector, because it handles in its own way the hidden details of std::vector's definition, or unless one has ideological reasons to use the objects of such class in place of std::vector's ones. However, the creators of the standard on C++ did not provide std::vector with any interface (in the form of protected members) that such inherited class could take advantage of in order to improve the vector in a specific way. Indeed, they had no way to think of any specific aspect that might need extension or fine-tune additional implementation, so they did not need to think of providing any such interface for any purpose.

The reasons for the second option can be only ideological, because std::vectors are not polymorphic, and otherwise there is no difference whether you expose std::vector's public interface via public inheritance or via public membership. (Suppose you need to keep some state in your object so you cannot get away with free functions). On a less sound note and from the ideological point of view, it appears that std::vectors are a kind of "simple idea", so any complexity in the form of objects of different possible classes in their place ideologically makes no use.

其他回答

如果你正在考虑这个问题,那么你显然已经把办公室里的语言书呆子都干掉了。有了他们,为什么不直接做呢

struct MyVector
{
   std::vector<Thingy> v;  // public!
   void func1( ... ) ; // and so on
}

这将避免所有可能出现的错误,可能会意外地向上转换你的MyVector类,你仍然可以访问所有的向量操作,只需添加一个小.v。

我认为很少有规则是应该百分之百地盲从的。听起来你已经考虑了很多,并且相信这是一条正确的道路。所以——除非有人提出很好的具体理由不这样做——我认为你应该继续你的计划。

There is no reason to inherit from std::vector unless one wants to make a class that works differently than std::vector, because it handles in its own way the hidden details of std::vector's definition, or unless one has ideological reasons to use the objects of such class in place of std::vector's ones. However, the creators of the standard on C++ did not provide std::vector with any interface (in the form of protected members) that such inherited class could take advantage of in order to improve the vector in a specific way. Indeed, they had no way to think of any specific aspect that might need extension or fine-tune additional implementation, so they did not need to think of providing any such interface for any purpose.

The reasons for the second option can be only ideological, because std::vectors are not polymorphic, and otherwise there is no difference whether you expose std::vector's public interface via public inheritance or via public membership. (Suppose you need to keep some state in your object so you cannot get away with free functions). On a less sound note and from the ideological point of view, it appears that std::vectors are a kind of "simple idea", so any complexity in the form of objects of different possible classes in their place ideologically makes no use.

不从std::vector公开继承的主要原因是缺少虚析构函数,这有效地阻止了您多态地使用后代。特别是,你不允许删除std::vector<T>*,它实际上指向一个派生对象(即使派生类没有添加成员),但编译器通常不能警告你。

在这些条件下允许私有继承。因此,我建议使用私有继承并从父方法转发所需的方法,如下所示。

class AdVector: private std::vector<double>
{
    typedef double T;
    typedef std::vector<double> vector;
public:
    using vector::push_back;
    using vector::operator[];
    using vector::begin;
    using vector::end;
    AdVector operator*(const AdVector & ) const;
    AdVector operator+(const AdVector & ) const;
    AdVector();
    virtual ~AdVector();
};

您应该首先考虑重构您的算法,以抽象它们所操作的容器类型,并将它们保留为自由模板函数,正如大多数回答者所指出的那样。这通常是通过让算法接受一对迭代器而不是容器作为参数来实现的。

实际上:如果派生类中没有任何数据成员,就不会有任何问题,甚至在多态使用中也不会。只有在基类和派生类的大小不同和/或有虚函数(即v-table)时,才需要虚析构函数。

但在理论上:来自c++ 0x FCD中的[expr.delete]:在第一个替代方案(删除对象)中,如果要删除的对象的静态类型与其动态类型不同,则静态类型应是要删除的对象的动态类型的基类,并且静态类型应具有虚析构函数或行为未定义。

但是你可以从std::vector中私有地派生而没有问题。 我使用了以下模式:

class PointVector : private std::vector<PointType>
{
    typedef std::vector<PointType> Vector;
    ...
    using Vector::at;
    using Vector::clear;
    using Vector::iterator;
    using Vector::const_iterator;
    using Vector::begin;
    using Vector::end;
    using Vector::cbegin;
    using Vector::cend;
    using Vector::crbegin;
    using Vector::crend;
    using Vector::empty;
    using Vector::size;
    using Vector::reserve;
    using Vector::operator[];
    using Vector::assign;
    using Vector::insert;
    using Vector::erase;
    using Vector::front;
    using Vector::back;
    using Vector::push_back;
    using Vector::pop_back;
    using Vector::resize;
    ...