为什么要编译?
struct A {};
struct B {
B(A& _a) : a(_a) {}
A &a;
};
void f1(A&) {}
void f2(const B &b) { f1(b.a); }
int main() {
A a;
B b{a};
f2(b);
return 0;
}
里面的f2()b是const,所以我的理解是b.a也应该是const。但它确实编译,编译器允许调用f1()。
替换'A&一个;'在结构B中带'A a;'它不再有效。 现在在f1()b.a中确实是const:
invalid initialization of reference of type 'A&' from expression of type 'const A'
请帮助我理解这一点......谢谢。
答案 0 :(得分:5)
当一个对象为const
时,它不会导致引用成员也成为const
,因为引用对象本身不是对象的一部分。引用成员只是表示某个其他对象的地址的一条信息。 B
对象本身是否不可变不应该影响是否应该改变它引用的对象。
如果您使B::a
成员成为非引用,如A a;
中那样,则B
对象实际上将包含A
个对象,因此当前者是const
,后者也是。{/ p>
答案 1 :(得分:1)
在f2()中,b是const,所以我的理解是b.a也应该是const。
是的。如果实例是const
那么它的成员也是。{但请看成员的类型:
A & a;
这是对A
的引用。使const
产生对A
的持续引用:
A & const a;
不对常量A
的引用。
答案 2 :(得分:0)
严格来说,没有经常引用。有对常量对象的引用。
在B类中,数据成员a
被声明为对A类非常量对象的引用。
A &a;
并且此引用作为参数传递给接受对非常量对象的引用的函数
void f1(A&) {}
void f2(const B &b) { f1(b.a); }
因此代码编译成功。