Подтвердить что ты не робот

Доступ к функции базового класса

class Base
{
    public: void foo(){}
};

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

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

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

4b9b3361

Ответ 1

В стандарте в разделе 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 С++), тогда как g++ и MSVС++ (правильно) отклоняют его.

Ответ 2

Right.

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

MinGW g++ 4.4.1:

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

Visual С++ 10.0:

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

Comeau Online 4.3.10.1:

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

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

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

Oops!

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

Я постараюсь сообщить об этом Комо.

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

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

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

Ответ 3

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

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

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

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