Например, предположим, что я написал такой код:
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
? Или есть способ лучше?
a
находится внутри class B
. Чтобы получить доступ к закрытому члену класса, вам может потребоваться общедоступный метод в class B
, например, int get_a() { return a; }
.
Если вы хотите получить только 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;
}
«и А не дружит с Б», вы имеете в виду, что Б не дружит с А? Я почти уверен, что это невозможно, так как вам нужно заранее получить полное определение A или B.