2017-02-26 39 views
-1

爲什麼編譯?C++常量在參考上丟失

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確實是常量:

invalid initialization of reference of type 'A&' from expression of type 'const A' 

請幫我理解這...謝謝。

回答

5

當對象是const時,它不會導致引用成員也變爲const,因爲引用不是對象本身的一部分。引用成員只是代表其他對象地址的一條信息。 B對象本身是否是不可變的,不應該影響是否應該可能對它引用的對象進行變異。

如果使B::a成員非基準,如A a;,那麼B對象實際上將自身內部包含一個A對象,所以當前者是const,後者也將如此。

1

Inside f2() b is const, so my understanding was that b.a should also be const.

它是。如果實例是const那麼它的成員也是。但看看會員的類型:

A & a; 

這是對A的參考。使該const產生一個恆定參考A

A & const a; 

一個參照本發明的恆定A

+0

錯誤:'const'限定符不能應用於'A&' – Jarek

+0

誰說的? (在什麼情況下?)是的,它是[完全多餘](https://isocpp.org/wiki/faq/const-correctness#const-ref-nonsense)。無論如何,它更像是思想實驗;) –

0

嚴格地說,沒有恆定的引用。有對常量對象的引用。

在類B的數據成員a被聲明等向型A.

A &a; 

的非恆定對象的引用和該引用作爲參數傳遞給一個函數,它接受一個引用傳遞非恆定對象

void f1(A&) {} 
void f2(const B &b) { f1(b.a); } 

因此代碼編譯成功。