Как и почему можно изменить уровень доступа участника? - PullRequest
6 голосов
/ 04 ноября 2010

Я закончил кодировать (с некоторой помощью) что-то вроде этого вчера:

#include <iostream>

using namespace std;

class A
{
    public:
        virtual void foo(){cout << "A::foo\n";}
};

class B : private A
{
    private:
        virtual void foo(){ cout << "B::foo\n";}
        void DoSomething(SomeOtherClass& o){o.DoSomething(*static_cast<A*>(this));}
};

Я попытался изменить метод наследования:

class B : public A
{
    private:
        virtual void foo(){ cout << "B::foo\n";}
};

int main()
{
    A* a = new B;
    a->foo();
}

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

EDIT:

Во втором случае выводом будет B::foo.

Ответы [ 2 ]

3 голосов
/ 04 ноября 2010
using namespace std; 

class A 
{ 
    public: 
        virtual void foo(){cout << "A::foo\n";} 
}; 

class B : public A 
{ 
    private: 
        virtual void foo(){ cout << "B::foo\n";} 
}; 

int main() 
{ 
    A* a = new B; 
    a->foo(); 
} 

Это работает, потому что во время компиляции компилятор может видеть только, что a - это указатель на базовый класс A, а foo() - это открытый метод, вызываемый на a, что совершенно правильно. Виртуальная привязка происходит динамически во время выполнения после компиляции, эта виртуальная привязка решает, что фактический вызов - B::foo(), а не A::foo(), что является снижением производительности при использовании виртуализма.

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

Может не ответить на все ваши вопросы напрямую, тем не менее я решил выложить его здесь для дальнейшего использования.Также, пожалуйста, отнеситесь к этому с солью, поскольку это основано на моем понимании событий, которые произошли в мире C ++ Standard, а не фактических данных.

Чтение this .У меня нет ARM, но в статье приводятся необходимые подробности.

Примечание 115 в C ++ 0x говорит:

115) Объявления доступа устарели;декларации об использовании членов (7.3.3) предоставляют лучшие способы сделать то же самое.В более ранних версиях языка C ++ декларации доступа были более ограничены;они были обобщены и сделаны эквивалентными декларациям использования в интересах простоты.Программистам рекомендуется использовать декларации использования, а не новые возможности объявлений доступа, в новом коде.

В заключение:

Я думаю, что ARM изначально запретил это:

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

Но позже, я думаю, когда Стандарт эволюционировал , это в конечном итоге было разрешено

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