2013-08-01 73 views
7

Như tự tập thể dục, tôi đã viết mã này rất đơn giản:Phải là kiểu tham chiếu được khởi tạo trong danh sách khởi tạo hàm dựng không?

#include <iostream> 

int gIndex = 3; 

template <class T> class Array 
{ 
public: 
    explicit Array(int size); 
    T& operator[](int i) { return m_data[i]; } 
    T operator[](int i) const { return m_data[i]; } 
    T getAnchorPoint() const { return m_data[m_anchor]; } 
private: 
    T* m_data; 
    int m_size; 
    int& m_anchor; 
}; 

template <class T> Array<T>::Array(int size) : m_size(size), m_data(new T[size]) 
{ 
    memset(m_data, 0, size*sizeof(T)); 
    m_anchor = gIndex; 
} 

int main() 
{ 
    Array<double> a(10); 
    return 0; 
} 

tôi nhận được một lỗi biên dịch, mà nói:

error C2758: 'Array<T>::m_anchor' : must be initialized in constructor base/member initializer list

Nó chưa bao giờ xảy ra, những gì mang lại cho tôi để hỏi này câu hỏi:

Phải bất kỳ loại tham chiếu lớp học nào được khởi tạo trong danh sách khởi tạo hàm tạo không?

Nếu có, tại sao? Đó có phải là liên quan đến một cách nào đó để thực tế là một loại tài liệu tham khảo không bao giờ có thể được phân công lại?

Có nhiều loại phải được khởi tạo trong danh sách khởi tạo hàm dựng không?

Trả lời

12

Có loại tham chiếu lớp thành viên nào phải được khởi tạo trong danh sách khởi tạo của hàm tạo không?

Có.

Nếu có, tại sao? Có phải đó liên quan đến việc thực tế là một loại tham chiếu không bao giờ có thể được tái chỉ định?

Đó là một phần lý do. Một phần khác là vì một tham chiếu phải được khởi tạo, và nó không có hàm tạo mặc định.

Có nhiều loại phải được khởi tạo trong danh sách khởi tạo hàm dựng không?

Bất kỳ loại nào không có toán tử gán (có thể là bản sao hoặc di chuyển) hoặc hàm tạo mặc định. Điều này rõ ràng bao gồm (nhưng không giới hạn) const thành viên vì chúng không thể được sửa đổi khi chúng được xây dựng.


Như một quy tắc của ngón tay cái, bạn nên (hầu như) luôn luôn thích để khởi tạo các thành viên của bạn trong danh sách khởi tạo của nhà xây dựng: tại sao chu kỳ thải đầu tiên mặc định-xây dựng một đối tượng và sau đó chỉ gán cho nó (nếu điều này thậm chí còn có thể), khi bạn có thể xây dựng nó một cách chính xác ngay từ đầu?

+1

Tôi thực sự xấu hổ khi hỏi điều đó, nhưng loại tham chiếu không có toán tử gán? – Billie

+3

@ user1798362 không, một tham chiếu nó chỉ là một bí danh cho một cái gì đó khác. Khi bạn "gán" cho một tham chiếu, bạn thực sự gán cho đối tượng mà nó đề cập đến. – juanchopanza

+0

Như tôi đã nghĩ. cảm ơn! – Billie

3

Phải loại bất kỳ loại tham chiếu lớp thành viên nào trong danh sách khởi tạo hàm tạo không?

Có.

Điều đó có liên quan đến thực tế là loại tham chiếu không bao giờ có thể được chỉ định lại không?

Có, cộng với thực tế là không có "không có" hoặc xây dựng mặc định để tham chiếu. Nó là một bí danh cho một đối tượng khác, và nó phải được ràng buộc với nó ngay từ đầu.Bạn không thể làm điều này (điều này không phải là bên trong một định nghĩa lớp):

int main() 
{ 
    int& iref; // ERROR 
    int i = 42; 
    int& iref2 = i; // OK 
} 

iref phải bí danh một cái gì đó.

+0

Cảm ơn ví dụ này, bây giờ tôi đã hoàn toàn có nó! – Billie

-1
Must any class-member reference type be initialized in the constructor initialization list? 

Có, chúng tôi luôn sử dụng danh sách trình khởi tạo để khởi tạo thành viên tham chiếu của lớp học.

If so, why? Is that related somehow to the fact that a reference type can never be reassigned? 

Một hàm tạo có hai giai đoạn là khởi tạo và tính toán. Vì vậy, ngay cả khi bạn không sử dụng danh sách initializer cho một trình biên dịch thành viên dữ liệu sẽ khởi tạo nó với giá trị ngẫu nhiên. Và trong giai đoạn tính toán thường bắt đầu bằng '{' của phần thân hàm dựng, nếu bạn thực hiện một phép gán thì trình biên dịch sẽ khiếu nại khi thành viên tham chiếu đã được intialized. Vì vậy, cơ hội duy nhất của bạn để khởi tạo thành viên như vậy là danh sách khởi tạo constructor.

Are there more types that must be initialized in constructor initialization list? 

Có, thành viên dữ liệu const là loại khác mà bạn cần danh sách khởi tạo.

+0

Trình biên dịch không phàn nàn vì gán (gán cho một tham chiếu thực sự gán cho đối tượng được tham chiếu, không có vấn đề gì với điều đó) hoặc vì tham chiếu đã được khởi tạo, nhưng vì nó * không được * khởi tạo ở vị trí đầu tiên (đó là bất hợp pháp). – syam

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