声称使用标准 C++ 容器作为基类是错误的,这让我感到惊讶.
The claim that it is a mistake ever to use a standard C++ container as a base class surprises me.
如果声明不是滥用语言...
If it is no abuse of the language to declare ...
// Example A
typedef std::vector<double> Rates;
typedef std::vector<double> Charges;
... 那么,声明...的危害究竟是什么
... then what, exactly, is the hazard in declaring ...
// Example B
class Rates : public std::vector<double> {
// ...
} ;
class Charges: public std::vector<double> {
// ...
} ;
B 的积极优势包括:
A 的积极优势包括:
这两种方法都优于使用原始容器,因为如果实现从 vector
Both approaches are superior to using a raw container, because if the implementation changes from vector<double> to vector<float>, there's only one place to change with B and maybe only one place to change with A (it could be more, because someone may have put identical typedef statements in multiple places).
我的目标是这是一个具体的、可回答的问题,而不是讨论更好或更坏的实践.显示由于从标准容器派生而可能发生的最糟糕的事情,而使用 typedef 可以防止这种情况发生.
My aim is that this be a specific, answerable question, not a discussion of better or worse practice. Show the worst thing that can happen as a consequence of deriving from a standard container, that would have been prevented by using a typedef instead.
毫无疑问,将析构函数添加到类 Rates 或类 Charges 将是一种风险,因为 std::vector 没有将其析构函数声明为虚拟的.示例中没有析构函数,也不需要一个.销毁 Rates 或 Charges 对象将调用基类析构函数.这里也不需要多态性.挑战在于展示由于使用派生而不是 typedef 而导致的一些不好的事情发生.
Without question, adding a destructor to class Rates or class Charges would be a risk, because std::vector does not declare its destructor as virtual. There is no destructor in the example, and no need for one. Destroying a Rates or Charges object will invoke the base class destructor. There is no need for polymorphism here, either. The challenge is to show something bad happening as a consequence of using derivation instead of a typedef.
考虑这个用例:
#include <vector>
#include <iostream>
void kill_it(std::vector<double> *victim) {
// user code, knows nothing of Rates or Charges
// invokes non-virtual ~std::vector<double>(), then frees the
// memory allocated at address victim
delete victim ;
}
typedef std::vector<double> Rates;
class Charges: public std::vector<double> { };
int main(int, char **) {
std::vector<double> *p1, *p2;
p1 = new Rates;
p2 = new Charges;
// ???
kill_it(p2);
kill_it(p1);
return 0;
}
是否有任何可能的错误,即使是任意不幸的用户也可以在 ???这将导致 Charges(派生类)出现问题,但不会导致 Rates(typedef)出现问题?
Is there any possible error that even an arbitrarily hapless user could introduce in the ??? section which will result in a problem with Charges (the derived class), but not with Rates (the typedef)?
在 Microsoft 实现中,vector
In the Microsoft implementation, vector<T> is itself implemented via inheritance. vector<T,A> is a publicly derived from _Vector_Val<T,A> Should containment be preferred?
标准容器没有虚拟析构函数,因此你不能多态地处理它们.如果您不这样做,并且使用您的代码的每个人都没有这样做,那么这本身就不是错误".但是,为了清楚起见,您最好还是使用合成.
The standard containers do not have virtual destructors, thus you cannot handle them polymorphically. If you will not, and everyone who uses your code doesn't, it's not "wrong", per se. However, you are better off using composition anyway, for clarity.
这篇关于从 C++ STL 容器派生是否有任何真正的风险?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!