我有一个由嵌套的 STL 容器组成的数据结构:
typedef std::map<Solver::EnumValue, double> SmValueProb;
typedef std::map<Solver::VariableReference, Solver::EnumValue> SmGuard;
typedef std::map<SmGuard, SmValueProb> SmTransitions;
typedef std::map<Solver::EnumValue, SmTransitions> SmMachine;
这种形式的数据只在我的程序中短暂使用,除了简单地存储它们的数据之外,没有太多的行为可以附加到这些类型。然而,编译器 (VC++2010) 提示生成的名称太长。
将类型重新定义为 STL 容器的子类而无需进一步详细说明似乎可行:
typedef std::map<Solver::EnumValue, double> SmValueProb;
class SmGuard : public std::map<Solver::VariableReference, Solver::EnumValue> { };
class SmTransitions : public std::map<SmGuard, SmValueProb> { };
class SmMachine : public std::map<Solver::EnumValue, SmTransitions> { };
认识到 STL 容器并非旨在用作基类,在这种情况下实际上是否存在任何危险?
最佳答案
存在一种危险:如果您在指向没有virtual
析构函数的基类的指针上调用delete
,就会出现未定义行为。否则,你很好。
至少理论上是这样。实际上,在 MSVC ABI 或 Itanium ABI(gcc、Clang、icc 等)中,delete
基类没有虚拟析构函数 (-Wdelete-non-virtual-dtor
使用 gcc 和 clang,提供类具有虚拟方法)仅当您的派生类添加具有非平凡析构函数的非静态属性时才会导致问题(例如 std::string
).
在你的具体情况下,这似乎很好......但是......
...您可能仍然希望封装(使用组合)并公开有意义的(面向业务的)方法。它不仅危险性更小,而且比 it->second.find('x')->begin()
...
关于C++ typedef 与未详细说明的继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13560329/