Сведения о вопросе

Codeliver

16:31, 27th August, 2020

Теги

c++   override   metrowerks    

Есть ли способ предотвратить переопределение метода в подклассах?

Просмотров: 642   Ответов: 14

Кто-нибудь знает о языковой функции или технике в C++, чтобы предотвратить чрезмерное использование дочерним классом определенного метода в родительском классе?

class Base {
public:
    bool someGuaranteedResult() { return true; }
};

class Child : public Base {
public:
    bool someGuaranteedResult() { return false; /* Haha I broke things! */ }
};

Даже если он не является виртуальным, это все равно разрешено (по крайней мере, в компиляторе Metrowerks, который я использую), все, что вы получаете, - это предупреждение о времени компиляции о скрытии невиртуальной наследуемой функции X.



  Сведения об ответе

ASER

12:11, 24th August, 2020

Когда вы можете использовать спецификатор final для виртуальных методов (введенный с C++11), вы можете это сделать. Позвольте мне процитировать мой любимый сайт doc :

При использовании в объявлении виртуальной функции final указывает, что функция не может быть переопределена производными классами.

Адаптированный к вашему примеру это было бы похоже:

class Base {
public:
    virtual bool someGuaranteedResult() final { return true; }
};

class Child : public Base {
public:
    bool someGuaranteedResult() { return false; /* Haha I broke things! */ }
};

При компиляции:

$ g++ test.cc -std=c++11
test.cc:8:10: error: virtual function ‘virtual bool Child::someGuaranteedResult()’
test.cc:3:18: error: overriding final function ‘virtual bool Base::someGuaranteedResult()’

Когда вы работаете с компилятором Microsoft, также обратите внимание на ключевое слово sealed.


  Сведения об ответе

padenie

09:48, 8th August, 2020

Есть пара идей:

  1. Сделайте свою функцию приватной.
  2. Не делайте свою функцию виртуальной. Однако это на самом деле не мешает функции быть затененной другим определением.

Кроме этого, я не знаю языковой функции, которая будет блокировать вашу функцию таким образом, чтобы она не была перегружена и все еще могла быть вызвана через указатель/ссылку на дочерний класс.

Удачи вам!


  Сведения об ответе

PAGE

09:56, 8th August, 2020

Похоже, что вы ищете эквивалент ключевого слова Java языка final , которое предотвращает переопределение метода подклассом .

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


  Сведения об ответе

appple

23:35, 21st August, 2020

Для пояснения скажу, что большинство из вас неправильно поняли его вопрос. Он не спрашивает о методе "overriding", он спрашивает, Есть ли способ предотвратить "hiding" или нет. И самый простой ответ - это "there is none!".

Вот его пример еще раз

Родительский класс определяет функцию:

int foo() { return 1; }

Дочерний класс, наследующий Родительский, определяет ту же функцию AGAIN (не переопределяя):

int foo() { return 2; }

Это можно сделать на всех языках программирования. Ничто не мешает этому коду компилироваться (кроме установки на компиляторе). Лучшее, что вы получите, - это предупреждение о том, что вы скрываете метод родителя. Если вы вызовете дочерний класс и вызовете метод foo, вы получите 2. Вы практически нарушили этот код.

Вот о чем он спрашивает.


  Сведения об ответе

COOL

04:53, 22nd August, 2020

(a) я не думаю, что сделать функцию частной-это решение, потому что это просто скроет функцию базового класса от производного класса. Производный класс всегда может определить новую функцию с той же сигнатурой. (b) сделать функцию невиртуальной также не является полным решением, поскольку , если производный класс переопределяет ту же самую функцию, всегда можно вызвать производную функцию класса путем привязки времени компиляции, т. е. obj.someFunction(), где obj является экземпляром производного класса.

Я не думаю, что есть способ сделать this.Also,i хотел бы знать причину вашего решения запретить производным классам переопределять функции базового класса.


  Сведения об ответе

screen

02:48, 18th August, 2020

предупреждение времени компиляции о скрытии невиртуальной наследуемой функции X.

измените настройки компилятора, чтобы сделать его ошибкой, а не предупреждением.


  Сведения об ответе

lats

21:06, 28th August, 2020

Я догадываюсь, что компилятор предупреждает Вас о том, что скрывается !! Действительно ли он отменяется ?

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

Это очень интересно. Попробуйте сделать небольшую автономную тестовую программу для вашего компилятора.


  Сведения об ответе

VERSUION

14:18, 28th August, 2020

Я искал то же самое и вчера пришел к этому [довольно старому] вопросу.

Сегодня я нашел аккуратное ключевое слово c++11 : final . Я подумал, что это может быть полезно для следующих читателей.

http://en.cppreference.com/w/cpp/language/final


  Сведения об ответе

прога

13:46, 6th August, 2020

Технически u может предотвратить переопределение виртуальных функций до be be. Но вы никогда не сможете изменить или добавить больше. Это не полная помощь. Лучше использовать комментарий перед функцией, как предлагает faq lite.


  Сведения об ответе

#hash

08:50, 5th August, 2020

Если вы обращаетесь к дочернему классу как к типу его родителя, то невиртуальная функция вызовет версию родительского класса.

т.е.:

Parent* obj = new Child();


  Сведения об ответе

Chhiki

11:48, 4th August, 2020

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

Так что по умолчанию C++ делает то, что вы хотите.


  Сведения об ответе

прога

22:13, 22nd August, 2020

Попытка запретить кому-либо использовать то же имя, что и ваша функция в подклассе, мало чем отличается от попытки запретить кому-либо использовать то же глобальное имя функции, которое вы объявили в связанной библиотеке.

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


  Сведения об ответе

SKY

04:20, 21st August, 2020

В вашем примере ни одна функция не переопределяется. Вместо этого он скрыт (это своего рода вырожденный случай перегрузки). Ошибка находится в коде дочернего класса. Как и предлагал csmba, все, что вы можете сделать, это изменить настройки компилятора (если это возможно) ; это должно быть нормально, если вы не используете стороннюю библиотеку, которая скрывает свои собственные функции.


  Сведения об ответе

PROGA

15:35, 19th August, 2020

Методы C++ являются закрытыми и не переопределяемыми по умолчанию.

  • Нельзя переопределить частный метод
  • Нельзя переопределить метод, не являющийся virtual

Может быть, вы имеете в виду перегрузку?


Ответить на вопрос

Чтобы ответить на вопрос вам нужно войти в систему или зарегистрироваться