Я думаю, что в вашем дизайне есть недостаток. Если я правильно понимаю, вы хотите ограничить тип переменной члена базового класса:
struct Entrance {};
struct Door : public Entrance {};
struct Building
{
Entrance * entrance; // raw pointer just for the sake of clarity
};
struct House : public Building
{
// Building::entrance must always be a door
};
Этого можно добиться, используя методы доступа (getter / setter) к entrance
и проверяя тип, выбрасывая исключение, если вход не дверь, но это нарушит принцип замены Лискова : вы не сможет манипулировать House
с, как если бы они были Building
с:
struct Drawbridge : public Entrance {};
House house;
Drawbridge bridge;
Building & building = house;
building.setEntrance(bridge);
// Oups, I'm trying to install a drawbridge on my house!
Некоторые библиотеки выполняют такого рода ограничения (например, ReadOnlyCollection<T>
выдает исключение при попытке изменить его содержимое), но, на мой взгляд, это не чистый дизайн. Если интерфейс коллекции утверждает, что я могу добавить элементы в коллекцию, то коллекция только для чтения - это , а не коллекция (поскольку она не поддерживает добавление элементов).
Здесь можно применить те же аргументы: a House
- это , а не a Building
, поскольку он не может содержать все виды Entrance
s.