使用标准C++容器作为基类曾经是一个错误的说法令我感到惊讶。
如果不滥用该语言,则声明...
// Example A
typedef std::vector<double> Rates;
typedef std::vector<double> Charges;
...那么,确切地说是什么危险...
// Example B
class Rates : public std::vector<double> {
// ...
} ;
class Charges: public std::vector<double> {
// ...
} ;
B的积极优势包括:
A的积极优势包括:
两种方法都优于使用原始容器,因为如果将实现从vector 更改为vector ,则B只能更改一个地方,而A只能更改一个地方(可能更多,因为有人可能将相同的typedef语句放在多个位置)。
我的目标是,这是一个具体的,可以回答的问题,而不是讨论更好或更坏的做法。显示由于从标准容器派生而可能发生的最坏的事情,这可以通过使用typedef来避免。
编辑:
毫无疑问,将析构函数添加到Rates或Charge类中是有风险的,因为std::vector不会将其析构函数声明为virtual。该示例中没有析构函数,也不需要一个析构函数。销毁Rates或Charges对象将调用基类的析构函数。这里也不需要多态。挑战在于显示由于使用派生而不是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)出现问题?
在Microsoft实现中,vector 本身是通过继承实现的。 vector 是从_Vector_Val 公开派生的,应该首选围堵吗?
最佳答案
标准容器没有虚拟析构函数,因此您无法进行多态处理。如果您不这样做,并且使用您的代码的每个人都不这样做,那么它本身就不是“错误的”。但是,为了清楚起见,最好还是使用合成。
关于c++ - 从C++ STL容器派生有真正的风险吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/922248/