Как правильно использовать объявление друга во вложенном классе? - PullRequest
0 голосов
/ 27 октября 2018

Например, предположим, я сделал код вроде:

class A
{
private:
    class B
    {
    private:
        int a;
        friend int A::foo(B &b);
    };
    int foo(B &b)
    {
        return b.a;
    }
};

Поскольку a в B является частным, для использования a в функции foo из A я бы использовал friend, чтобы foo действительно мог получить доступ к a. Однако этот код выдает ошибку, что он не может получить доступ к a. В чем проблема кода, и как мне изменить код, оставив a закрытым и A не являющимся другом B? Или есть лучший способ?

1 Ответ

0 голосов
/ 27 октября 2018

Если вы хотите получить только класс a из B, вам нужна функция получения.Это должен быть самый простой способ.

class B
{
private:
    int a;
public:
    // provide getter function
    const int& getMember_a()const { return a; }
};

и в функции foo

const int& foo(const B &b)const 
{
    return b.getMember_a(); // call the getter to get the a
}

Относительно вопроса вашего кода;в строке friend int A::foo(B &b); в B классе, он не знает, что функция A::foo.Поэтому нам нужно переслать объявление int foo(B &); перед классом B.Тогда вопрос;знает ли A::foo(B &) о B.Тоже нет.Но, к счастью, C ++ позволяет иметь неполный тип, также объявляя классы вперед.Это означает, что, следуя по пути, вы можете достичь желаемой цели.

class A
{
private:
    class B;      // forward declare class B for A::foo(B &)
    int foo(B &); // forward declare the member function of A
    class B
    {
    private:
        int a;
    public:
        friend int A::foo(B &b);
    };
};
// define, as a non-member friend function
int A::foo(B &b)
{
    return b.a;
}
...