2011-07-25 30 views
68

thể trùng lặp:
C++ initialization listsC++: Nơi để khởi tạo các biến trong constructor

gì là những ưu/nhược điểm của việc khởi tạo biến tùy theo lựa chọn 1 vs 2 lựa chọn?

class MyClass 
{ 
public: 
    MyClass(float f, char a); 
private: 
    float mFloat; 
    char mCharacter; 
    bool mBoolean; 
    int mInteger; 
}; 

MyClass::MyClass(float f, char a) : mFloat(f), mBoolean(true) // option 1. 
{ 
    // option 2 
    mCharacter = a; 
    mInteger = 0; 
} 

Chỉnh sửa: Tại sao tùy chọn 2 quá phổ biến?

+0

không còn trùng lặp với chỉnh sửa được thêm. vì tùy chọn 1 rõ ràng là tốt hơn, tôi tò mò tại sao lựa chọn 2 là quá phổ biến. –

+0

Nó có thể là một bản sao, nhưng có vẻ như không có câu trả lời nào về câu hỏi khác là đầy đủ. –

Trả lời

92

Tóm lại, luôn thích danh sách khởi tạo khi có thể. 2 lý do:

  • Nếu bạn không đề cập đến một biến trong danh sách khởi tạo của lớp, hàm tạo sẽ mặc định khởi tạo trước khi nhập nội dung của hàm tạo mà bạn đã viết. Điều này có nghĩa là tùy chọn 2 sẽ dẫn đến mỗi biến được ghi thành hai lần, một lần cho khởi tạo mặc định và một lần cho phép gán trong phần thân của hàm tạo.

  • Ngoài ra, như đã đề cập bởi mwigdahl và avada trong các câu trả lời khác, thành viên const và thành viên tham chiếu có thể chỉ được được khởi tạo trong danh sách khởi tạo.

Cũng lưu ý rằng các biến luôn khởi tạo vào thứ tự mà chúng được khai báo trong phần khai báo lớp, không theo thứ tự chúng được liệt kê trong danh sách khởi tạo (với lời cảnh báo thích hợp kích hoạt một trình biên dịch sẽ cảnh báo bạn nếu một danh sách là được viết theo thứ tự). Tương tự như vậy, các destructors sẽ gọi các thành phần destructors theo thứ tự ngược lại, từ đầu đến cuối trong khai báo lớp, sau khi mã trong destructor của lớp của bạn đã thực thi.

+0

Cảm ơn câu trả lời thông tin. Quan điểm của bạn về phương án 2, là tiêu chuẩn hay là một số trình biên dịch cụ thể? Tôi không cho rằng nó sẽ quá khó để một trình biên dịch tối ưu hóa các quyền ban đầu. Tôi thích lựa chọn 2 vì nó sạch hơn. – 0fnt

+5

Không phải trình biên dịch có thể tối ưu hóa việc khởi tạo tự động không cần thiết không? Tôi có nghĩa là, C# và Java có thể làm điều đó, vì vậy nên C + +, phải không? – Joey

+0

Đây được gọi là "danh sách khởi tạo", không phải là "danh sách bộ khởi tạo". – duleshi

19

Mặc dù không áp dụng cho ví dụ cụ thể này, Tùy chọn 1 cho phép bạn khởi tạo biến thành viên của loại tham chiếu (hoặc const loại, như được chỉ ra bên dưới). Tùy chọn 2 không. Nói chung, Lựa chọn 1 là cách tiếp cận mạnh mẽ hơn.

+0

Phải, nhưng anh ta không có loại tham chiếu nào. Vì vậy, lựa chọn 2 là tốt. –

+0

Trong ví dụ cụ thể của mình (có vẻ như được giả tạo hơn là lấy từ mã thực), yep! Trong trường hợp tổng quát hơn, Phương án 1 thường rất cao cấp, đó là những gì tôi nhận được. Tôi sẽ chỉnh sửa để làm cho nó rõ ràng hơn. – mwigdahl

3

Tùy chọn 1 cho phép bạn sử dụng một địa điểm được chỉ định chính xác để khởi tạo rõ ràng biến thành viên.

8

Xem Should my constructors use "initialization lists" or "assignment"?

Tóm lại: trong trường hợp cụ thể của bạn, nó không thay đổi bất cứ điều gì. Nhưng:

  • cho các thành viên lớp/struct với nhà thầu, nó có thể hiệu quả hơn để sử dụng tùy chọn 1.
  • chỉ lựa chọn 1 cho phép bạn khởi tạo các thành viên tham khảo.
  • chỉ lựa chọn 1 cho phép bạn khởi tạo các thành viên const
  • chỉ lựa chọn 1 cho phép bạn khởi tạo các lớp cơ sở sử dụng constructor của họ
  • chỉ phương án 2 cho phép bạn khởi tạo mảng hoặc cấu trúc mà không có một constructor.

Tôi đoán tại sao tùy chọn 2 phổ biến hơn là tùy chọn 1 không nổi tiếng, cũng không phải là lợi thế của nó. Cú pháp của tùy chọn 2 cảm thấy tự nhiên hơn đối với lập trình C++ mới.

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