Дружба и наследство - PullRequest
       27

Дружба и наследство

0 голосов
/ 29 марта 2019

Я работаю над небольшим проектом, и я застрял, потому что я не очень понимаю, как дружба и наследство взаимодействуют друг с другом.Я покажу вам пример кода.

namespace a
{
    class Foo
    {
    public:
        Foo(int x) : m_x(x) {}
    protected:
        friend class b::Derived;
        friend class a::Base;
        int m_x;
    };

    class Base
    {
    public:
        Base(Foo foo) : m_foo(foo) {}
    protected:
        Foo m_foo;
    };
}
namespace b
{
    class Derived : public a::Base
    {
    public:
        Derived(a::Foo foo)
            : Base(foo)
        {
            m_foo.m_x;
        }
    };
}
e0265: at line 29: member a::Foo::m_x (declared at line 10) is inaccessible

Очевидно, Derived не может получить доступ к защищенным элементам Foo, по-видимому, потому что Derived :: m_foo является производным членом, поэтому создание Derived завершится неудачно.Может кто-нибудь объяснить мне это подробно?

Ответы [ 2 ]

0 голосов
/ 29 марта 2019

Я нашел проблему.Пространство имен b и, следовательно, производный класс не были видны объявлению друга в Foo.Когда я переадресовал объявление b и производное, все работало как задумано, и производный мог получить доступ к закрытым / защищенным членам.

0 голосов
/ 29 марта 2019

Очевидно, что Derived не может получить доступ к закрытым членам Foo, по-видимому, потому что Derived :: m_foo является производным членом, поэтому создание Derived завершится неудачей.

Извините, это не очевидноенедоразумение друга.

Класс друга может получить доступ к любому атрибуту.

У вас есть несвязанная ошибка кодирования ... комментарии показывают, что вы пропустили инициализацию (Base :: m_foo)в базе.Исправьте это, добавьте несколько элементов данных в Foo, а затем запустите демонстрацию:

#include <iostream>
using std::cout, std::endl; 

class Foo
{
public:
   Foo(int x): m_x(x){}
   ~Foo(){}

   int m_z;   // add public

protected:
   int m_y;   // add protected

private:      // change to private
   friend class Derived;
   int m_x;
};

class Base
{
public:
   Base() : m_foo(0) // add m_foo Initialization (with 0)
      {}
   virtual ~Base(){}
protected:
   Foo m_foo;
};

class Derived : public Base
{
public:
   Derived(Foo foo)
      {
         foo.m_y   = 11;
         foo.m_z   = 22;
         std::cout << foo.m_x << "   "
                   << foo.m_y << "   "
                   << foo.m_z << std::endl;  //friend class can access
      }
};

class T914_t // ctor and dtor compiler provided defaults
{
public:
   int operator()(int argc, char* argv[]) { return exec(argc, argv);  }

private: // methods

   int exec(int , char** )
      {
         Foo     f(99);
         Derived d(f);

         return 0;
      }

}; // class T914_t

int main(int argc, char* argv[]) { return T914_t()(argc, argv); } // call functor

Типичный вывод из класса Производный ctor с доступом к личным, защищенным и общедоступным атрибутам данных:

99 11 22 * ​​1018 *

...