Подтвердить что ты не робот

Собственное наследство VS-композиция: когда использовать что?

Собственный состав наследования VS.

У меня немного путаницы, когда нужно использовать их. Так как частные наследования печатают, в некотором смысле, цепочку наследования, учитывая:

class A
{
private:
    int z;
protected:
    int y;
public:
    int x;
};

class B : private A
{
    /* B data members and methods */
    /* B has access only to A public and protected */
};

class C : public B
{
    /* can access no fields of B */
};

C не сможет использовать ни одно из полей B. Когда я буду использовать личное наследование и когда я буду использовать композицию?

спасибо!

4b9b3361

Ответ 1

Эта запись в С++ FAQ отвечает на ваши вопросы.

Репликация здесь:

Используйте композицию, когда можете, частное наследование, когда вам нужно.

Обычно вы не хотите иметь доступ к внутренним функциям слишком большого числа других классов, а частное наследование дает вам некоторую дополнительную мощность (и ответственность). Но частное наследство не является злым; это просто более дорого, чтобы поддерживать, поскольку это увеличивает вероятность того, что кто-то изменит что-то, что нарушит ваш код.

Допустимое долгосрочное использование для частного наследования - это когда вы хотите создать class Fred, который использует код в class Wilma, а код из class Wilma должен вызывать функции-члены из вашего нового класса, Fred. В этом случае Fred вызывает не-виртуальные в Wilma и Wilma вызовы (обычно чистые виртуальные) сами по себе, которые переопределяются Fred. Это было бы намного сложнее с композицией.

class Wilma {
 protected:
   void fredCallsWilma()
     {
       std::cout << "Wilma::fredCallsWilma()\n";
       wilmaCallsFred();
     }
   virtual void wilmaCallsFred() = 0;   // A pure virtual function
 };

 class Fred : private Wilma {
 public:
   void barney()
     {
       std::cout << "Fred::barney()\n";
       Wilma::fredCallsWilma();
     }
 protected:
   virtual void wilmaCallsFred()
     {
       std::cout << "Fred::wilmaCallsFred()\n";
     }
 };