Это не неопределенное поведение. Ссылка const
, являющаяся членом B
, означает только то, что экземпляр B
не может изменить его через эту ссылку. Однако, поскольку это ссылка, что-то еще может изменить ее - включая других членов B
, которые имеют свою собственную не-const
ссылку на тот же экземпляр A
.
Сравните дополнение члена c
к существующему классу B
, и обратите внимание, что мы успешно меняем его в пределах B::changeA()
через ссылку, отличную от const
, а также с C::change()
в main()
:
#include <iostream>
class A {
int x;
public:
A(int x): x(x){}
void change(int y){
x = y;
}
friend std::ostream & operator << (std::ostream & os, const A & a){
os << a.x;
return os;
}
};
class C
{
A& a;
public:
C(A& a) : a{a} {}
void change(int y) { a.change(y); }
};
class B {
const A & a;
C& c;
public:
B(const A & a, C& c) : a(a), c{c} {}
friend std::ostream & operator << (std::ostream & os, const B & b){
os << b.a;
return os;
}
void changeA(int y) { c.change(y); }
};
int main(){
A a(1);
C c(a);
B b(a,c);
std::cout << a << ' ' << b << '\n';
a.change(2);
std::cout << a << ' ' << b << '\n';
b.changeA(3);
std::cout << a << ' ' << b << '\n';
c.change(4);
std::cout << a << ' ' << b << '\n';
}
Посмотри, как он работает на Coliru , который печатает:
1 1
2 2
3 3
4 4