Одновременное частное и публичное наследование в C ++ - PullRequest
1 голос
/ 28 декабря 2010

Предположим, класс Y публично наследует класс X.Возможно ли, чтобы класс Z унаследовал Y в частном порядке при публичном наследовании X?

Для большей ясности предположим, что X определяет публичные методы x1 и x2.Y наследует X, переопределяет x1 и предоставляет метод y.Позволяет ли C ++ третьему классу Z подкласс Y таким образом, что реализация Y x1 и y доступна для него в частном порядке, в то время как внешний мир видит, что он наследует X публично, т.е. имея только один публичный метод x2?

Ответы [ 5 ]

4 голосов
/ 28 декабря 2010

Да, это называется виртуальным наследованием.

struct X {
  virtual void x1();
  void x2();
};

struct Y : virtual X {
  void x1(); // overrides
  void y();
};

struct Z : private Y, virtual X { 

};

Люди не могут делать z.y() или z.x1(), но они могут делать z.x2() и могут конвертировать Z* в X*. Однако, как только они это сделают, они могут, конечно, позвонить converted->x1() и converted->x2().

Вы ничего не сказали о своей цели, но, похоже, вы действительно хотите сохранить Y в качестве указателя, хотя

struct X {
  virtual void x1();
  void x2();
};

struct Y : X {
  virtual void x1(); // overrides
  void y();
};

struct Z : X { 
  virtual void x1() { // overrides
    /* uses y->x1 */ 
  }
  Y *y;
};

Это выглядит мне более знакомым.

2 голосов
/ 28 декабря 2010

Я думаю, что использование оператора лучше заполняет эту роль, оно позволяет вам указать на Z, какие частные методы будут доступны:

class X
{
    public:
        virtual void x1() {}
        virtual void x2() {}

};

class Y: public X
{
public:
    virtual void x1() {}
};

class Z: private Y
{
public:
    using X::x2;

};
2 голосов
/ 28 декабря 2010

Прежде всего, я не совсем уверен, что понимаю ваше последнее предложение.

Позволяет ли C ++ для третьего класса Z подкласс Y таким образом, что реализация Y для x1 и y является конфиденциальнойдоступны для него, в то время как внешний мир видит, что он публично наследует X, т. е. имеет только один публичный метод x2?

Если Z публично наследует от X, то оба x1 иx2 будет доступно: хотя доступность x2 может быть изменена в Z, ничто не мешает внешнему миру 1016 * манипулировать Z с помощью указателя Xи позвоните x2.

При этом, вы также можете иметь Z наследовать в частном порядке от Y и публично от X, хотя, как указал Йоханнес, вы должны изучить виртуальное наследование.так как Z будет, таким образом, наследовать дважды от X.


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

class X
{
public:
    virtual void x1();
    virtual void x2();
};

class Y : public X
{
public:
    virtual void y();
    virtual void x1();
};

class Z : public X
{
public:
    explicit Z(X *x) : x_(x) {}

    virtual void x1() { x_->x1(); }
    virtual void x2() { x_->x2(); }

private:
    X *x_;
};

int main()
{
    Y y;
    Z z(&y);
}

В этом быстром и грязном примере кода Z - это X (публичное наследование), но повторно использует Y реализацию.

2 голосов
/ 28 декабря 2010

Конечно.Вы можете использовать using X::x2 в разделе public:.Конечно, если Y переопределяет x2, вы будете игнорировать это переопределение.

0 голосов
/ 29 декабря 2010

Если вы используете не виртуальное наследование X хотя бы в одном месте, вы получаете два отдельных подобъекта X с разными путями доступа и правами доступа.

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

...