当唯一的派生类不添加额外变量时,省略虚拟析构函数

时间:2013-12-11 05:53:47

标签: c++ inheritance virtual-destructor design-decisions

我有一个类Literal,它实际上只是(const int)的包装器。我想要一个继承自Literal的第二个类PositiveLiteral,但是有一个构造函数断言它的值是正的。

class Literal {
public:
    Literal(int x):x(x){}
    virtual ~Literal(){}
    // Other methods
private:
    const int x;
}

class PositiveLiteral : public Literal {
public:
    PositiveLiteral(int x):Literal(x) {
        assert(x > 0)
    }
}

通过这种方式,期望正文字的函数可以简单地将PositiveLiteral作为参数。然后我不需要在我的代码中放置显式断言,而且,如果这些断言失败,我可以立即看到原因。

除了在这种情况下,我不希望继承Literal。然而,因为有继承,我必须给Literal一个虚拟析构函数,以避免看似愚蠢的未定义行为,因为PositiveLiteral没有与Literal没有关联的exra信息。这只是一种维护断言而不必明确的方法。

完成相同任务的另一种方法是什么,而不需要在一个简单的包装类中使用虚方法?

1 个答案:

答案 0 :(得分:1)

除非你通过指向基类的指针进行动态分配和delete,否则你不需要拥有虚拟析构函数。


真正的问题在于设计层面。虽然每个PositiveLiteral值都是Literal值,但如果您引用的Literal实际上是PositiveLiteral,则可以为其分配负值...

在文献和论坛讨论中,这曾被称为椭圆与圆形问题,尽管相似性并不明显。

首先,要明确问题,只有不可变值PositiveLiteralLiteral可变PositiveLiteral是可变Literal的情况。

然后,实用的C ++解决方案是提供值转换而不是使用继承。

例如,这是用于智能指针的解决方案。


附录:我没有在OP的代码中看到该值为const。所以没有这样的问题。

实际问题是至少有一个编译器Visual C ++倾向于愚蠢地警告它无法生成一个拷贝赋值运算符;它可以通过声明一个没有实现的私有来关闭。 : - )