2011-12-12 24 views
23

giả sử chúng ta có một test.cpp như sau:Tại sao tôi không thể khai báo tham chiếu đến một đối tượng có thể thay đổi? ("Tài liệu tham khảo không thể được khai báo có thể thay đổi")

class A; 

class B 
{ 
    private: 
     A mutable& _a; 
}; 

Compilation:

$> gcc test.cpp 
test.cpp:6:20: error: reference ‘_a’ cannot be declared ‘mutable’ [-fpermissive] 

gcc của tôi:

$> gcc --version 
gcc (Ubuntu/Linaro 4.6.1-9ubuntu3) 4.6.1 
Copyright (C) 2011 Free Software Foundation, Inc. 
This is free software; see the source for copying conditions. There is NO 
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 

Tại sao?

+0

Bạn đang tìm kiếm một con trỏ? –

+0

Thậm chí nếu bạn có thể làm điều này nó sẽ là vô dụng vì C++ không chứa bất kỳ cú pháp nào có thể thay đổi tham chiếu. Bạn thậm chí không thể lấy địa chỉ bộ nhớ của một tham chiếu. Nếu bạn cố gắng lấy địa chỉ của đối tượng mà tham chiếu trỏ đến. – bames53

+0

Xin lỗi, tôi đã đặt câu hỏi sai. Đây không phải là một tham chiếu có thể thay đổi được, đây là một tham chiếu đến một đối tượng có thể thay đổi được! (Tôi đã thay đổi tiêu đề) – Martin

Trả lời

34

Không có lý do gì để một thành viên tham chiếu có thể thay đổi. Tại sao? Bởi vì hàm thành viên const thể thay đổi đối tượng được tham chiếu bởi một thành viên lớp:

class B { 
public: 
    B(int var) : n(var) {}; 
    void Set(int val) const { n = val; } //no error 
    void SetMember(int val) const { m = val; } //error assignment of member `B::m' in read-only structure 
protected: 
    int& n; 
    int m; 
}; 
+0

Cảm ơn bạn! Đây là câu trả lời tôi đang tìm kiếm. – Martin

10

Tham khảo chỉ có thể được chỉ định khi xây dựng một đối tượng và không thể sửa đổi sau đó. Do đó làm cho chúng mutable sẽ không có ý nghĩa, đó là lý do tại sao tiêu chuẩn không cho phép nó.

+2

Nhưng một tham chiếu có thể là const hoặc không const. Vì vậy, 'có thể thay đổi A & a' nên được ok, phải không? (Không gần trình biên dịch ngay bây giờ.) –

+2

Nhưng trong trường hợp này, 'biến thể' áp dụng cho đối tượng được tham chiếu, chứ không phải tham chiếu. –

9

Theo tiêu chuẩn: [7.1.1 Khoản 8]:

"Từ khoá có thể thay đổi có thể được áp dụng duy nhất tên của dữ liệu lớp thành viên (9.2) và không thể được áp dụng cho tên tuyên bố const hoặc tĩnh , và không thể áp dụng cho thành viên tham chiếu. "

Vì vậy, nó chỉ là bất hợp pháp.

2

Điều này có thể thổi tâm trí của bạn đi, nhưng một tài liệu tham khảo là không bao giờ có thể thay đổi (không thể được thực hiện để tham khảo đối tượng khác) và giá trị tham chiếu phải lúc nào cũng có thể thay đổi (trừ khi bạn có một tham chiếu đến const):

#include <iostream> 

struct A 
{ 
    int& i; 
    A(int& n): i(n) {} 
    void inc() const 
    { 
    ++i; 
    } 
}; 

int main() 
{ 
    int n = 0; 
    const A a(n); 
    a.inc(); 
    std::cout << n << '\n'; 
} 

một phương pháp const nghĩa là một top-level const-vòng loại được thêm vào các thành viên. Đối với một tham chiếu này không có gì (= int & const a;), đối với một con trỏ nó làm cho con trỏ, không phải là chòm sao (= int* const p, không const int* p;).

Các vấn đề liên quan