Arm*_*yan 182 c++ oop inheritance stl vector
好吧,这真的很难承认,但我现在确实有很强的诱惑力来继承std::vector
.
我需要大约10个定制的矢量算法,我希望它们直接成为矢量的成员.但我自然也希望拥有剩下std::vector
的界面.好吧,作为一个守法的公民,我的第一个想法是std::vector
在MyVector
课堂上有一个成员.但是我必须手动重新编写所有std :: vector的接口.打字太多了.接下来,我考虑了私有继承,所以我不会using std::vector::member
在公共部分写一些方法而不是重新提取方法.实际上这也很乏味.
在这里,我确实认为我可以简单地从公开继承std::vector
,但在文档中提供警告,不应该多态地使用此类.我认为大多数开发人员都有足够的能力去理解这不应该以多态方式使用.
我的决定绝对没有道理吗?如果是这样,为什么?你能提供一个替代方案,其他成员实际上是成员,但不会涉及重新输入所有vector的界面吗?我对此表示怀疑,但如果可以,我会很高兴.
此外,除了一些白痴可以写类似的事实
std::vector<int>* p = new MyVector
Run Code Online (Sandbox Code Playgroud)
使用MyVector 有任何其他现实危险吗?通过说现实,我放弃像想象一个带有指向矢量的指针的函数...
好吧,我已经陈述了我的情况.我犯罪了.现在由你来原谅我了不起:)
Sta*_*tas 151
实际上,公共继承没有任何问题std::vector
.如果你需要这个,那就去做吧.
我建议只有在真的有必要时这样做.只有你不能用自由功能做你想做的事情(例如应该保持一些状态).
问题是这MyVector
是一个新实体.这意味着新的C++开发人员在使用它之前应该知道它到底是什么.std::vector
和之间有什么区别MyVector
?哪个更适合在这里和那里使用?如果我需要移动std::vector
到MyVector
?我可以用swap()
或不用吗?
不要生产新的实体只是为了让事情看起来更好.这些实体(尤其是这种实体)不会生活在真空中.他们将生活在混合环境中,不断增加熵.
Kos*_*Kos 90
整个STL的设计方式使得算法和容器是分开的.
这导致了不同类型的迭代器的概念:const迭代器,随机访问迭代器等.
因此,我建议你接受这个约定,并设计你的算法,使他们不关心他们正在处理的容器是什么 - 他们只需要一个特定类型的迭代器,他们需要执行他们的操作.
另外,让我转发一下Jeff Attwood的一些好评.
Bas*_*evs 56
不std::vector
公开继承的主要原因是缺少虚拟析构函数,有效地阻止了后代的多态使用.特别是,你都不准到delete
一个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();
};
Run Code Online (Sandbox Code Playgroud)
您应该首先考虑重构您的算法以抽象它们正在操作的容器类型,并将它们保留为免费模板化函数,正如大多数回答者所指出的那样.这通常通过使算法接受一对迭代器而不是容器作为参数来完成.
Cra*_*rks 34
如果你正在考虑这个问题,你显然已经杀死了你办公室里的语言学生.随着他们走开,为什么不做
struct MyVector
{
std::vector<Thingy> v; // public!
void func1( ... ) ; // and so on
}
Run Code Online (Sandbox Code Playgroud)
这将避开可能由于意外地向上转换MyVector类而导致的所有可能的错误,并且您仍然可以通过添加一点来访问所有向量操作.v
.
Kar*_*tel 19
你有什么希望完成的?只提供一些功能?
C++惯用的方法是编写一些实现该功能的免费函数.有可能你真的不需要std :: vector,特别是你正在实现的功能,这意味着你实际上通过尝试继承std :: vector而失去了可重用性.
我强烈建议您查看标准库和标题,并思考它们的工作原理.
NPE*_*NPE 14
我认为在100%的时间里应该盲目遵循很少的规则.听起来你已经给了它很多想法,并且确信这是要走的路.所以 - 除非有人提出不这样做的具体原因 - 我认为你应该继续你的计划.
小智 7
没有理由继承,std::vector
除非有人想要创建一个不同于std::vector
它的类,因为它以自己的方式处理std::vector
定义的隐藏细节,或者除非有意识形态的理由使用这类的对象代替std::vector
的.但是,C++标准的创建者没有提供std::vector
任何接口(以受保护成员的形式),这样的继承类可以利用这些接口以特定方式改进向量.实际上,他们没有办法考虑可能需要扩展或微调其他实现的任何特定方面,因此他们不需要考虑为任何目的提供任何此类接口.
第二种选择的原因只能是意识形态的,因为std::vector
s不是多态的,否则无论是std::vector
通过公共继承还是通过公共成员公开公共接口都没有区别.(假设您需要在对象中保留一些状态,这样您就无法使用自由函数).从一个不那么合理的角度来看,从意识形态的角度来看,似乎std::vector
s是一种"简单的想法",因此在意识形态上不同可能类别的对象形式的任何复杂性都没有用处.