2012-07-07 7 views
10

Đây là câu hỏi không liên quan về mã trong this question, liên quan đến chức năng mẫu sau.lỗi: khởi tạo không hợp lệ tham chiếu loại 'int &' từ biểu thức loại 'const int'

template <class T> 
class Object : public Container { 
public: 
    T& object; 

    Object(const T& obj) : object(obj) {} 
}; 

Đây là mã mà các cuộc gọi constructor:

template <class T> 
void Array::add_element(const T& element) 
{ 
    vec.push_back(new Object<T>(element)); 
} 

Mã này biên dịch tốt, nhưng ngay sau khi tôi thêm một dòng trong main mà gọi đó là:

Array array; 
int i = 3; 
array.add_element(i); 

tôi nhận được cảnh báo trình biên dịch: error: invalid initialization of reference of type 'int&' from expression of type 'const int'.

Điều đó nghĩa là gì? Tôi đã thông qua một số int. Không được tự động biến thành một số const int& cho tôi? Tại sao trình biên dịch lại phàn nàn?

+6

Gợi ý: 'T & đối tượng;' - Ngoài ra, 'const T & obj = nullptr' không thực hiện bất kỳ ý nghĩa , bạn không thể khởi tạo tham chiếu đến 'nullptr'. – Xeo

+0

Làm thế nào là một gợi ý? Đó chính là cách 'đối tượng' đã được khai báo. Và cảm ơn bạn, tôi sẽ thay đổi điều đó. – anthropomorphic

+2

Đó là một gợi ý vì bạn không thể khởi tạo tham chiếu không const từ tham chiếu const - const-correctness 101. – ildjarn

Trả lời

12

obj là tham chiếu const. object là tham chiếu không phải const.

Bạn không thể khởi tạo tham chiếu không const từ tham chiếu const, bởi vì làm như vậy sẽ đánh bại mục đích có tham chiếu const ở vị trí đầu tiên.

Nếu bạn muốn bản sao Object của mình để có thể sửa đổi int được truyền cho hàm tạo của nó, thì hàm tạo nên tham chiếu không tham chiếu. Nếu không, thì thành viên dữ liệu phải là tham chiếu const.

Trong mọi trường hợp, bạn đang lưu trữ sự cố cho chính mình nếu bạn sử dụng new để phân bổ các đối tượng có tham chiếu dưới dạng thành viên dữ liệu. Đó là vấn đề của bạn để đảm bảo rằng bạn xóa Object trước i đi ra khỏi phạm vi (hoặc dù sao, đảm bảo rằng các Object không sử dụng thành viên object sau i đi ra khỏi phạm vi.

+0

Câu trả lời hay. Nó hoạt dộng bây giờ. – anthropomorphic

8

Bạn đang cố gắng gán một tham chiếu const đến một tham chiếu const không. này có nghĩa là lớp Object của bạn có thể sửa đổi nội dung của đối tượng.

const int myConstNumber = 4; 
Object<int> intObj(myConstNumber); 

intObj.object = 3; // you have indirectly modified the value of myConstNumber 

C++ không cho phép bạn làm điều đó . bạn có thể tạo một bản sao của đối tượng hoặc thêm const vào thuộc tính của bạn

template <class T> 
class Object : public Container { 
public: 
    T object; // valid 

hoặc

template <class T> 
class Object : public Container { 
public: 
    const T& object; // valid 

trong trường hợp này, bạn không thể sửa đổi đối tượng

+1

Cảm ơn, câu trả lời của bạn cũng tốt, nhưng trước tiên đến trước được phục vụ, xin lỗi =/ – anthropomorphic

+6

Không sao đâu, tôi ở đây để trợ giúp, không phải vì kudo. :) – ilmale