Спецификатор доступа, в то время как методы переопределения

Предположите, что у Вас есть класс, который определяет виртуальные методы с общественностью спецификатора доступа. Можно ли изменить спецификатор доступа на переопределенных методах? Я принимаю нет. Поиск объяснения.

7
задан Pradyot 19 April 2010 в 22:54
поделиться

4 ответа

4
ответ дан 6 December 2019 в 19:34
поделиться

Ответ: вроде как. Вы можете изменить доступ только к членам, к которым имеет доступ производный класс. Тип наследования не имеет значения - он контролирует только доступ по умолчанию для унаследованных членов (до определенной точки, следуя другим правилам).

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

Пример:

class Foo
{
protected:
        void protected_member();

private:
        void private_member();

public:
        void public_member();
};

class Bar : private Foo
{
public:
        using Foo::protected_member;
        using Foo::private_member;
        using Foo::public_member;
};

int main(int, const char**)
{
        Bar bar;

        return 0;
}

Приведенный выше код вызывает следующую ошибку в g ++ 4.1.2:

main.C: 7: error: 'void Foo :: private_member ()' is private

main.C: 14: ошибка: в этом контексте

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

7
ответ дан 6 December 2019 в 19:34
поделиться

Вы определенно можете. Но в этом нет смысла. Если это публичное наследование, то вы всегда можете привести объект к его базе. Если это частное наследование, все базовые методы по умолчанию уже являются частными. В случае защищенного наследования вы можете сделать базовый метод закрытым, чтобы предотвратить его вызов возможными производными классами, но я действительно не понимаю, зачем он может понадобиться.

2
ответ дан 6 December 2019 в 19:34
поделиться

Да, вы можете, и на самом деле вам даже не нужно переопределять или использовать что-либо виртуальное.

class ABC {
public: // or this may be protected, no difference
    void woof();
    void moo();
};

class D : private ABC { // now woof and moo are private
public:
    using ABC::woof; // using declaration to make woof public again
    ABC::moo; // access declaration (deprecated) does the same
};

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

С другой стороны, без специальных объявлений в D , общедоступный интерфейс ABC действительно был бы недоступен через D потому что вы не сможете выполнить апкастинг до ABC . И если бы woof и moo были виртуальными , вам нужно сделать переопределения частными , чтобы скрыть их. Возможно, это лучший ответ на вопрос.

0
ответ дан 6 December 2019 в 19:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: