При наследовании от открытого интерфейса, почему не имеет значения, является ли реализация публичной или частной? - PullRequest
1 голос
/ 27 июня 2011

Возможно, я очень устал, слишком устал или слишком далеко от C ++, но сегодня меня это действительно удивило:

#include <iostream>

class Interface
{
public:
    virtual int aa() const = 0;
    virtual int bb() const = 0;
};

class Usage : public Interface
{
private:
    virtual int aa() const
    {
        int a = 10 * 10;
        return a;
    }

    virtual int bb() const
    {
        int b = 20 * 20;
        return b;
    }
};

int main(int argc, char* argv[])
{
    Interface* i = new Usage();
    std::cout << i->bb() << std::endl;

    return 0;
}

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

Как это правило вызывается в C ++?

Ответы [ 3 ]

7 голосов
/ 27 июня 2011

Это указано в пункте 11.6.1 стандарта:

Правила доступа (пункт 11) для виртуальной функции определяются ее объявлением и не зависят от правил для функцииэто позже отменяет это.[ Пример - в основном такой же, как ваш ] Доступ проверяется в точке вызова с использованием типа выражения, используемого для обозначения объекта, для которого вызывается функция-член.Доступ к функции-члену в классе, в котором она была определена, в общем случае неизвестен.

1 голос
/ 27 июня 2011
Interface* i = new Usage();
std::cout << i->bb() << std::endl;

Это работает, потому что имя функции разрешается в зависимости от типа объекта static.

Здесь объект i, тип static которого равен Interface*, имеет public имя функции bb().Следовательно, компилятор не видит никаких проблем, поскольку это соответствует требованию вызова функции-члена.

Также обратите внимание, что accessibility (public, private и protected) являются конструкциями времени компиляции.Во время выполнения такой вещи не существует.Компилятор может обнаружить любое нарушение правил, связанных с доступностью, только во время компиляции.Он не может знать, что происходит во время выполнения.

Таким образом, даже если i указывает на объект, тип которого Usage, который определил bb() в разделе private, компилятор в порядке, как отмечалось ранее для типа statici по-прежнему Interface* с функцией public bb().Компилятор не беспокоится о типе объекта dynamic и о том, как он переопределяет функцию, потому что он не может, именно по той причине, что его dynamic ;определяется во время выполнения.

0 голосов
/ 27 июня 2011

private означает, что вы не можете наследовать от него.protected или public, от которого вы можете наследовать, но ничто не мешает вам ограничить видимость более низким уровнем (т. Е. public до protected или private; или protected до private) в вашем топекласс.

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