2015-08-10 16 views
5

Nếu tôi sử dụng tham chiếu const cho thành viên khác, có thể tham chiếu này bị vô hiệu không?Tham chiếu const có phải là thành viên an toàn

class Class { 
public: 
    const int &x{y}; 
private: 
    int y; 
}; 

Ví dụ khi tôi sử dụng trường hợp của lớp này trong một vector làm tăng khả năng của mình sau một push_back. Theo tiêu chuẩn, tất cả các vòng lặp và tham chiếu sẽ bị vô hiệu nếu một vec-tơ phải tăng dung lượng của nó. Tham chiếu vẫn hợp lệ sau đó?

+0

Tôi sẽ ngạc nhiên nếu bạn có thể đẩy nó vào vectơ và có 'x' điểm mà bạn nghĩ. –

+0

Không được đẩy trở lại là tốt cho mỗi trường hợp 'Lớp' mới được chèn vào? Dữ liệu sẽ được sao chép vào vectơ với x trỏ đến vị trí y mới. – 0ax1

+0

Nếu bạn lấy tham chiếu trước 'push_back()', nó sẽ không trỏ đến phần tử đó bên trong vectơ. 'push_back()' lấy một bản sao. –

Trả lời

6

Điều này hiện không an toàn, như khi bạn sao chép một thể hiện của Class, x sẽ tham chiếu y của đối tượng được sao chép, chứ không phải riêng của nó y. Bạn có thể thấy điều này bằng cách chạy đoạn mã sau:

int main() 
{ 
    Class a{}; 
    std::vector<Class> vec; 
    vec.push_back(a); 

    //these lines print the same address 
    std::cout << &(a.x) << std::endl; 
    std::cout << &(vec[0].x) << std::endl; 
} 

Bạn có thể khắc phục điều này bằng cách viết riêng copy constructor và phân công chức năng của bạn để khởi tạo một cách chính xác x:

Class (const Class& rhs) : x{y}, y{rhs.y} {} 

này là an toàn, bởi vì xy sẽ chỉ bị phá hủy cùng với đối tượng của bạn. Việc vô hiệu tham chiếu cho std::vector có nghĩa là tham chiếu đến các phần tử vectơ:

Class c; 
std::vector<Class> vec; 
vec.push_back(c); 

Class& cr = vec[0]; 
//other operations on vec 
std::cout << c.x; //fine, that reference is internal to the class 
std::cout << cr.x; //cr could have been invalidated 
+1

Nó vẫn hoạt động nếu tôi ghi đè lên bản sao ctor và vectơ phải phát triển sau khi đẩy lùi? Các tham chiếu sau đó vẫn hợp lệ? – 0ax1

+0

Có, đó là đoạn cuối cùng và địa chỉ đoạn trích. – TartanLlama

3

Giả sử đây là tham chiếu đến một thành viên khác từ cùng một cá thể, bạn cần phải ghi đè lên hàm tạo bản sao để khởi tạo nó. Nhà xây dựng bản sao mặc định sẽ sao chép tham chiếu đến 'y' từ phiên bản cũ có thể bị vô hiệu.

Tại sao bạn cần tham chiếu đến thành viên là một câu hỏi khác.

P.S. bạn cũng cần phải ghi đè lên một toán tử gán cho cùng một lý do.

+0

Tôi nghĩ về nó như là một thay thế cho getter chung. – 0ax1

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