Виртуальный ненужный для защищенных функций - PullRequest
1 голос
/ 12 сентября 2011

Скажем, класс B происходит от класса A. Это оба заявляют f(). е защищен. Следовательно, f будет вызываться только внутри A и внутри B. f() нужно объявить виртуальным?

Вернее: скажем, C происходит от B происходит от A. B и A объявляют защищенные не виртуальные f(). Будет ли звонок на f() в C и B разрешаться на B::f() и в A на A::f()?

В таком случае, следует ли нам всегда избегать виртуального доступа для защищенных членов, чтобы иметь статическое разрешение? Это делается автоматически? Спасибо!

Ответы [ 4 ]

2 голосов
/ 12 сентября 2011

Пока вызов f() выполняется в функции, полученной из A (и не перегруженной / переопределенной в B или C), указатель this разрешается в A* и, следовательно, A::f() называется. Так что нет, вам все еще нужна виртуальная функция в этом случае.

1 голос
/ 12 сентября 2011

Объявление вашего защищенного метода virtual необходимо, когда вы хотите полиморфное поведение (примером этому является Шаблонный метод pattern ), и его следует избегать, когда вы нет.Однако в последнем случае вы не должны скрывать функцию с другой функцией, имеющей такую ​​же сигнатуру в подклассе, в противном случае вы получите удивительное поведение (подобное описанному в вашем втором абзаце), которое открывает возможность для незначительных ошибок.

0 голосов
/ 12 сентября 2011

Итак:

class A {
public:
  void f() { std::cout << "A::f\n"; }
};

class B : public A {
public:
  void f() { std::cout << "B::f\n"; }
};

Пока компилятор знает, что объект на самом деле является B, он будет вызывать f () в B. Но это не всегда так:

void callF(A* a)
{
  a->f();
}

B b;
callF(&b);  // prints A::f

Если вы хотите, чтобы такие функции, как callF, вызывали правильную функцию f (), сделайте ее virtual. Как правило, вы делаете функции виртуальными, если имеет смысл переопределить их в классе-потомке. Это часто относится к защищенным функциям.

0 голосов
/ 12 сентября 2011

Я немного заржавел на своем C ++, но я бы сказал, что "статическое разрешение" будет гарантировано только тогда, когда вы объявите метод private и, таким образом, вам потребуется virtual вместе с protected в вашем сценарии ...

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