好吧,这真的很难承认,但我确实有一个强烈的诱惑,从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还有其他现实的危险吗?通过说现实,我放弃了一些东西,比如想象一个函数,它接受一个指向向量的指针…

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


当前回答

是的,它是安全的,只要你小心不做不安全的事情……我想我从来没有见过有人用向量new,所以在实践中你可能没问题。然而,这并不是c++....中的常用习语

你能提供更多关于算法的信息吗?

有时你在设计上走了一条路,然后看不到你可能走的其他道路——你声称需要用10种新算法来做矢量,这一事实给我敲响了警钟——矢量真的可以实现10种通用算法吗?或者你试图做一个对象,它既是通用矢量,又包含特定的应用程序功能?

我当然不是说你不应该这样做,只是你所提供的信息敲响了警钟,这让我认为也许你的抽象是有问题的,有更好的方法来实现你想要的。

其他回答

实际上,std::vector的公共继承并没有什么问题。如果你需要这个,就去做那个。

我建议只有在确实有必要的时候才这样做。只有当你不能用自由函数做你想做的事情时(例如,应该保持一些状态)。

问题是MyVector是一个新实体。这意味着一个新的c++开发人员在使用它之前应该知道它到底是什么。std::vector和MyVector之间的区别是什么?哪一个更适合在这里和那里使用?如果我需要移动std::vector到MyVector怎么办?我可以只用swap()吗?

不要仅仅为了让某些东西看起来更好而创造新的实体。这些实体(尤其是如此常见的实体)不会生活在真空中。它们将生活在熵不断增加的混合环境中。

你希望完成什么?只是提供一些功能?

c++惯用的方法是编写一些实现该功能的自由函数。有可能您实际上并不需要std::vector,特别是对于您正在实现的功能,这意味着您实际上通过尝试继承std::vector而失去了可重用性。

我强烈建议您查看标准库和标头,并思考它们是如何工作的。

是的,它是安全的,只要你小心不做不安全的事情……我想我从来没有见过有人用向量new,所以在实践中你可能没问题。然而,这并不是c++....中的常用习语

你能提供更多关于算法的信息吗?

有时你在设计上走了一条路,然后看不到你可能走的其他道路——你声称需要用10种新算法来做矢量,这一事实给我敲响了警钟——矢量真的可以实现10种通用算法吗?或者你试图做一个对象,它既是通用矢量,又包含特定的应用程序功能?

我当然不是说你不应该这样做,只是你所提供的信息敲响了警钟,这让我认为也许你的抽象是有问题的,有更好的方法来实现你想要的。

整个STL被设计成算法和容器是分开的。

这就产生了不同类型迭代器的概念:const迭代器、随机访问迭代器等等。

因此,我建议你接受这个约定,并以这样的方式设计你的算法,即它们不会关心它们正在处理的容器是什么——它们只需要特定类型的迭代器来执行它们的操作。

另外,让我把你引向杰夫·阿特伍德的一些精彩评论。

不从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();
};

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