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

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信息。这只是维护断言而不必使其明确的一种方法。

在一个简单的包装类中,不需要虚拟方法又可以完成同一任务的另一种方法是什么?

最佳答案

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



真正的问题在于设计水平。因为虽然每个PositiveLiteral值都是一个Literal值,但是如果您引用的Literal实际上是一个PositiveLiteral,则可以为它指定一个负值…

在文献和论坛讨论中,尽管相似性并不明显,但该问题曾经被称为椭圆对圆问题。

首先,要非常清楚地说明问题,PositiveLiteralLiteral的唯一值是不可变的。可变的PositiveLiteral并非可变的Literal并非如此。

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

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



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

一个实际的问题是,至少一个编译器Visual C ++有一种愚蠢的警告,即它无法生成副本分配运算符。可以通过声明一个不执行的私有文件来关闭它。 :-)

关于c++ - 当唯一的派生类不添加任何额外变量时,省略虚拟析构函数,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/20511531/

10-12 14:48