#c #oop #inheritance
#c #ооп #наследование
Вопрос:
У меня есть простой родительский и базовый класс:
class X
{
public:
virtual void Method(){...}
};
class Z : public X
{
public:
virtual void Method(){ X::Method(); }
};
Я хочу реорганизовать это, чтобы новый класс Y
находился между ними в иерархии классов, так Z : Y
Y : X
что. Z::Method()
теперь должен вызывать Y::Method()
not X::Method()
. Но если я не изменю это, он все равно компилируется. По правде говоря, у меня много таких методов, и очень легко пропустить вызов X::...
при рефакторинге, что приведет к труднодоступным ошибкам.
Есть ли способ заставить компилятор предупредить меня, другими словами, сделать X
методы доступными Y
, но скрытыми от Z
?
Чтобы уточнить, это может быть только временное изменение, пока я выполняю рефакторинг, чтобы убедиться, что я ничего не пропустил.
Комментарии:
1. Обычный ответ: состав? Или частное наследование? Может быть, немного контекста было бы неплохо, зачем вам это нужно.
2. @idmean но затем
Y
необходимо реализовать сквозные методы для каждого метода, который вX
нем не переопределяет …?3. Итак, вы хотите, чтобы Y переопределял методы из X таким образом, чтобы Z больше не мог их вызывать. Я правильно понял?
4. Если вы хотите
X
, чтобы методы были доступныY
, но скрыты отZ
, вы можете изменить их сpublic
наprivate
на, но создатьY
friend
класс. Я бы не советовал оставлять это так навсегда, но если ваша цель — избавиться от такого поведения, это будет иметь такой эффект.5. @idmean нет, я хочу убедиться, что все места
Z
, в которых вызывается метод суперклассаX
, обновлены для вызоваY
.
Ответ №1:
Но если я не изменю это, он все равно компилируется. По правде говоря, у меня много таких методов, и очень легко пропустить вызов X:: … при рефакторинге, что приведет к труднодоступным ошибкам.
Чтобы уточнить, это может быть только временное изменение, пока я выполняю рефакторинг, чтобы убедиться, что я ничего не пропустил.
Поскольку вы описываете «при рефакторинге», вы можете временно добавить неполный тип X
Z
, который затеняет суперкласс X
вверх по иерархии:
class Z : public Y {
private:
struct X; // TODO(Mr. Boy): remove after finishing re-factoring.
public:
void Method() override { X::Method(); } // error! Z::X is incomplete
};
Любое квалифицированное использование X::...
in Z
завершится неудачей, поскольку поиск преобразуется в неполный вложенный тип X
.