2012-01-18 30 views
8

Gần đây, tôi đã đọc nhiều về các nhà xây dựng từ số C++ FAQ. Một trong các mục đề cập đến việc luôn sử dụng danh sách khởi tạo luôn tốt nhất, trái ngược với việc khởi tạo các thành viên lớp trong khối mã của chính hàm tạo.Khởi tạo các thành viên không phải là lớp con trỏ

Điều này là do trình biên dịch có xu hướng tạo nhiều bản sao của các thành viên lớp học, thay vì chỉ đơn giản là một bản sao.

Ví dụ

Tốt

Foo::Foo(void) 
    : mBar(new Bar) //pointer to some memory address 
{ 
} 

Bad

Foo::Foo(void) 
{ 
    mBar = new Bar; 
} 

Một điều nó cũng khẳng định (và, trong khi điều này liên quan đến nhà thầu, nó cũng liên quan đến tinh khiết khởi tạo các đối tượng trong các chi l từ thậm chí các hàm không thành viên) là khi khởi tạo một đối tượng thông qua các phương pháp như sau:

void f(void) 
{ 
    Foo foo(Bar()); //Bad. 

    foo.x(); //error 
} 

Bạn sẽ, và tôi trích dẫn: "[declare] a non-member function that returns a Foo object".

(để biết thêm, nhấp vào liên kết ở trên)

Các Câu hỏi

Bởi vì điều này, nó là khôn ngoan khi có những điều sau đây:

Hoặc ngay cả điều này:

Geometry::Geometry(void) 
    : mFaces(QVector<GLushort>), 
     mFinalized(false), 
     mNormals(QVector<QVector3D>), 
     mVerticies(QVector<QVector3D>) 

Vì cách mà t hese được phân bổ (tức là, thực tế rằng đây là những con trỏ không), nó làm cho tôi tự hỏi có hay không các đối tượng này thậm chí CẦN khởi tạo trong đầu. Nếu họ làm vậy, đây có phải là phương pháp chính xác để thực hiện nó không? Hoặc, có phương pháp khởi tạo tốt hơn không?

Làm thế nào điều này liên quan đến câu hỏi

này liên quan đến câu hỏi chung do cách mà các phương pháp phía sau C++ khởi constructor liên quan đến cả hai đối tượng khởi tạo sử dụng các hàm constructor, cùng với thực tế rằng tôi ngu dốt cho dù các đối tượng có được phân bổ trên stack hay không, vì vậy tôi tin rằng dù sao - (dù cách nào, các đối tượng không có phân bổ con trỏ) thậm chí cần khởi tạo ngay từ đầu.

Trả lời

12

Nếu biến thành viên thuộc loại lớp với hàm tạo mặc định do người dùng khai báo, bạn không cần phải đề cập rõ ràng trong danh sách khởi tạo: hàm tạo mặc định của nó sẽ được gọi là anyway, trong khi xây dựng, trước phần thân của hàm khởi tạo được nhập.

Nếu biến thành viên là kiểu nguyên thủy (như int hoặc bool) hoặc thuộc loại lớp không có bất kỳ nhà khai thác nào do người dùng khai báo, bạn cần khởi tạo rõ ràng, nếu không nó sẽ không được khởi tạo (và nó sẽ có một giá trị không xác định, bạn không thể đọc một đối tượng chưa được khởi tạo).

+0

Vì vậy, điều đó có nghĩa là, theo đoạn mã trên, tôi chỉ đang tạo nhiều bản sao của các đối tượng mà tôi đang phân bổ? – zeboidlund

+3

Khi bạn sử dụng 'mFaces (QVector < GLushort >())', bạn xây dựng một tạm thời 'QVector ', copy xây dựng' mFaces' từ đó đối tượng tạm thời, sau đó tiêu diệt đối tượng tạm thời. Vì vậy, có, bạn đang tạo ra nhiều đối tượng hơn cần thiết. –

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