Взаимодействие между реализацией интерфейса и частным наследованием - PullRequest
0 голосов
/ 04 мая 2018

Когда класс наследуется конфиденциально, все члены этого класса становятся закрытыми в дочернем классе. Однако в следующем примере мы можем получить косвенный доступ к частной унаследованной реализации функции doWork через AD (что указывает на использование указателя на тип R).

Как это разрешено? Виртуальный поиск игнорирует правила видимости, поскольку он выполняется во время выполнения?

#include <iostream>
using std::cout;

class R
{
public:
    virtual void doWork() = 0;
};

class RA : public virtual R
{
public:
    void doWork() { cout << "RA doWork\n"; };
};

class P : public virtual R, private RA
{
public:
    P() : RA() {};
};


class AD : public virtual R, private P
{
public:
    AD() : P() {};

    void doWork(int k) { cout << "AD Time dowork " << k << "\n";}
};

int main()
{
    AD ad;
    R* p = &ad;
    p->doWork();
}

При запуске приведенный выше код выведет «RA doWork». Я ожидал, что это приведет к ошибке времени выполнения, потому что определение doWork не будет доступно из p из-за частного наследования.

1 Ответ

0 голосов
/ 04 мая 2018

AD наследуется в частном порядке от P, но публично от R. На практике это означает, что открытые методы, объявленные в R, будут по-прежнему доступны в AD, но открытые методы, объявленные в P, но не в R, не будут доступны в AD. Так, например, если P выглядело так:

class P : public virtual R, private RA
{
public:
    P() : RA() {};
    void doWorkP() { std::cout << "doWorkP" << std::endl; }
};

Вы могли бы получить доступ к doWork через AD, но не doWorkP.

Если вы хотите сделать методы R недоступными в AD, просто наследуйте от R в частном порядке.

...