С ними связаны много разных интересных, скажем так особенностей, про которые эксперты из комментариев скажут, что все логично, так и надо, и вообще, а как вы хотели иначе?
Никогда такого не было и вот опять - нашел следующую веселую приколюху.
Пусть у нас есть вот такой класс:
class A {
int x;
public:
A(int a) : x(a) {}
class B {
int y;
public:
B(int b) : y(b) {}
void f(A& a, B& b){
b.y = 1;
a.x = 1;
}
};
};
Да, странненький и убогенький, но вообще весь мой код примерно такой.
Так вот в нем есть класс, у него есть вложенный класс, и в нем есть функция, которая модифицирует объекты и своего класса, и того, в который он вложен.
void f(A& a, B& b){
b.y = 1;
a.x = 1;
}
И как мы можем видеть из ссылки выше - все прекрасно работает, и проблем ни у кого не вызывает.
int main() {
auto a = A(1);
auto b = A::B(2);
b.f(a, b);
return 0;
}
Но давайте теперь сделаем эту функцию
friend и вынесем за пределы класса.
class A {
int x;
public:
A(int a) : x(a) {}
class B {
int y;
public:
B(int b) : y(b) {}
friend void f(A& a, B& b);
};
};
void f(A& a, A::B& b){
b.y = 1;
a.x = 1;
}
Милорд, у вас родился кудяблик, и эта штука перестала компилироваться:
int main() {
auto a = A(1);
auto b = A::B(2);
f(a, b);
return 0;
}
Потому что что? Потому что правильно, мы дружим только с B, а вот с A не дружим.
<source>:15:7: error: 'x' is a private member of 'A'
15 | a.x = 1;
| ^
<source>:2:9: note: implicitly declared private here
2 | int x;
|
Мне тут поступал запрос на глубину моих постов, поэтому я потратил целых 10 минут на изучение вопроса прежде чем пошел строчить гневный пост в интернеты, и нашел вот такое:
https://cplusplus.github.io/CWG/issues/3193.html
тут что-то про
inhabiting the class scope, и насколько я понял, вот такая ошибка компиляции - это самовольство компиляторов, а в стандарте про это вроде как ничего внятного сказано не было... Или было, но я, в скудоумии своем, не разобрался... Кароче, friend - это одна их тех вещей, которых я стараюсь избегать в своем коде... Рано или поздно я начну избегать всего С++