Доступ к функции базового класса - PullRequest
11 голосов
/ 29 ноября 2010
class Base
{
    public: void foo(){}
};

class Derived : public Base
{
    private:
    using Base::foo;
};

int main()
{
   Derived d;
   d.foo();
}

Законен ли код?Объявление using Base::foo находится в закрытом разделе производного класса.Так что вызов d.foo() не должен компилироваться, я прав?

Ответы [ 3 ]

5 голосов
/ 29 ноября 2010

правый.

Теперь проверка реальности & hellip;

MinGW g ++ 4.4.1:

x.cpp: В функции 'int main ()': x.cpp: 3: ошибка: void Base :: foo () недоступный
x.cpp: 15: ошибка: внутри этот контекст

Visual C ++ 10.0:

x.cpp (15): ошибка C2248: 'Derived :: foo': не может получить доступ к частному член объявлен в классе 'Производные'
x.cpp (9): см. объявление «Derived :: foo»
x.cpp (6): см. объявление «Derived»

Comeau Online 4.3.10.1:

В строгом режиме, с -tused, Compile удалось (но помните, Comeau онлайн компилятор не ссылается).
Скомпилировано с расширениями C ++ 0x включен.

Oops . И Комо это почти всегда верно! Ну, отключение расширений C ++ 0x, для C ++ 98 / C ++ 03:

В строгом режиме, с -tused, Compile удалось (но помните, Comeau онлайн компилятор не ссылается).
Скомпилировано с расширениями C ++ 0x Disabled.

Oops!

Ну, ты мой большой, как говорят в Норвегии (дословно переводится на английский).

Я бы попытался сообщить об этом Комо.

РЕДАКТИРОВАТЬ : поскольку Прасун также ответил, цитируя Священный Стандарт с его интерпретацией того, что противоречит тому, что я написал выше, хорошо, хорошо, standadese & hellip;

§11.3 / 1 «Доступ к члену базового класса может быть изменен в производном классе & hellip;» и т. Д., Что настолько ясно, насколько это возможно (интерпретация не требуется). И с конкретным примером. И нормативный текст о том, что это эквивалентно using декларации.

Приветствия & hth.,

1 голос
/ 29 ноября 2010

Стандарт в разделе 11.2 / 4 гласит

Член m доступен при названии в классе N, если

- m как член N является публичным, или

- m как член N является частным, и ссылка встречается у члена или друга класса N или

- m как член N защищен, и ссылка встречается у члена или друга класса N или в член или друг класса P, полученного из N, где m как член P является частным или защищенным, или

- существует базовый класс B из N, который доступен в исходной точке, и m доступен, когда назван в классе B .

Однако в стандарте также говорится, что

§11.3 / 1 "Доступ члена базового класса может быть изменен в производном классе.

В вашем коде доступ члена foo был изменен в производном классе. Поэтому код не должен компилироваться, но это все еще активная проблема с открытым статусом Поэтому некоторые компиляторы компилируют код (Comeau и Intel C ++), тогда как g ++ и MSVC ++ (правильно) отклоняют его .

0 голосов
/ 29 ноября 2010

using - это объявление пространства имен в этом примере (в отличие от пространства имен директива ).Это не объявление метода, поскольку вы, похоже, намереваетесь использовать его как.

Метод foo() является общедоступным в классе Base и все еще доступен в классе Derived.

Вы, похоже, намереваетесь сделать foo() класса Base недоступным.Хотя мог бы быть способ сделать это (я не знаю, у меня никогда не было причин пытаться это сделать), я полагаю, что это указывает на ошибку в логике вашего наследования, и вы можете подумать о редизайнеу наших классов.

Если ваш класс Derived не будет вести себя как класс Base, он не должен наследоваться от класса Base.

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