Исключение виртуального деструктора, когда единственный производный класс не добавляет дополнительных переменных

У меня есть класс Literal, который на самом деле просто оболочка для (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 не имеет связанной с ним exra-информации, которой нет у Literal. Это просто способ поддержать утверждение, не делая его явным.

Как еще можно выполнить ту же задачу без использования виртуального метода, который должен быть простым классом-оберткой?

0

Решение

Вам не нужно иметь виртуальный деструктор, если вы не делаете динамическое распределение и delete через указатель на базовый класс.


Настоящая проблема лежит на уровне дизайна. В то время как правда, что каждый PositiveLiteral значение является Literal значение, если у вас есть ссылка на Literal который действительно PositiveLiteralтогда вы можете присвоить ему отрицательное значение…

В литературе и на форумах это когда-то называлось проблемой эллипса и круга, хотя сходство не очевидно.

Во-первых, чтобы быть очень ясным о проблеме, это только для неизменные ценности это PositiveLiteral это Literal, это не случай, что изменчивый PositiveLiteral изменчивый Literal,

Затем практическое решение C ++ заключается в предоставлении преобразование стоимости вместо использования наследования.

Например, это решение, используемое для умных указателей.


добавление: Я не смог увидеть, что в коде ОП значение const, Так что нет такой проблемы.

Практическая проблема состоит в том, что по крайней мере один компилятор, Visual C ++, имеет тенденцию глупо предупреждать о своей неспособности генерировать оператор присваивания копии; это можно закрыть, объявив частный без реализации. 🙂

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]