В C++ возможно явное явное обновление
Предположим, что A
происходит от B
, Есть ли способ запретить неявный upcast, как в B *x = new A()
сделав явное приведение, например, необходимым?
3 ответа
Там нет никакого способа, чтобы полностью предотвратить это преобразование.
Вы могли бы предотвратить это в большинстве мест (но не в друзьях или членах A
) с использованием частного наследования или путем замены наследования отношением сдерживания или агрегации (где A
содержит экземпляр или указатель / ссылку на B
Скорее наследование). Тогда функция-член может имитировать явное приведение:
B * x = new A(); // not allowed
A * a = new A(); // OK
B * b = a->to_B(); // OK
Но вы должны подумать о том, какое поведение вы на самом деле хотите предотвратить, вместо того, чтобы совершать совершенно нормальную работу, требующую перепрыгивания через довольно странный обруч. Почти наверняка есть лучший способ решить вашу конкретную проблему.
Это невозможно и противоречит правилам полиморфизма. Поскольку A является производным от B, A является B. Таким образом, приведение не требуется, B является родительским классом A. Любой экземпляр A может быть заменен на экземпляр B.
Это то, что вы хотите в принципе, потому что это позволяет программировать в сторону интерфейсов. Обычно интерфейс, хотя интерфейсы не существуют в C++, определяется с помощью некоторого абстрактного класса. Код обычно находится в лучшей форме, если вы можете продолжать ссылаться на интерфейс и держаться подальше от фактической реализации определенного интерфейса.
Для этого вы можете создать класс-оболочку, например:
template<typename T>
class MyPtr
{
public:
MyPtr(T* t) : t(t) {}
template <typename U>
MyPtr(U*) = delete;
MyPtr operator = (T* t) { this->t = t; return *this; }
template <typename U>
MyPtr operator = (U* t) = delete;
operator T* () const { return t; }
private:
T* t;
};