2013-07-18 31 views
12

Đoạn 8.5p7 của C++ 11 tiểu bang Tiêu chuẩn:Cần làm rõ với 8.5.p7 trong C++ 11 Chuẩn

Để giá trị khởi tạo một đối tượng kiểu T có nghĩa là:

  • nếu T là loại lớp (có thể cv đủ điều kiện) (Điều 9) với hàm tạo do người dùng cung cấp (12.1), thì hàm khởi tạo mặc định cho T được gọi (và khởi tạo không đúng nếu T có không thể truy cập mặc định hàm tạo);

  • nếu T là một (có thể cv-đủ điều kiện) phi đoàn lớp loại mà không có một constructor dùng cung cấp, sau đó các đối tượng được zero-khởi và nếu T của constructor mặc định ngầm-tuyên bố là phi tầm thường, hàm tạo đó được gọi.

  • nếu T là loại mảng, thì mỗi phần tử được khởi tạo giá trị;

  • nếu không, đối tượng là không được khởi tạo.

Tôi gặp sự cố khi hiểu các ký tự in đậm ở trên. Cách gọi bổ sung của hàm tạo ngầm mặc định của T có thể thay đổi khởi tạo bằng không, điều đó vừa xảy ra trong trường hợp này?

Trả lời

16

Dưới đây là một ví dụ cụ thể:

class A { 
    int a; 
public: 
    A() : a(1) {} 
}; 

class B { 
    int b; 
    A c; 
}; 

B rơi vào thể loại này - đó là một kiểu lớp phi công đoàn mà không có một constructor dùng cung cấp. Vì vậy, nếu B được khởi tạo giá trị, trước tiên nó sẽ không được khởi tạo (do đó cả hai bc.a sẽ được đặt thành 0), và sau đó hàm khởi tạo mặc định sẽ được gọi (hàm này sẽ gọi hàm tạo A và đặt c.a thành 1).

Bằng sự cai trị as-if, những có thể được kết hợp thành một bước duy nhất của tôi ưu hoa (mà sẽ thiết lập b-0 và c.a-1), như không ai có thể thấy đối tượng giữa không khởi tạo và các nhà xây dựng mặc định .

+0

+1 Khá rõ ràng – Belloc

+0

Cần lưu ý rằng VC++ không thực hiện đúng cách này. C++ 98 có các quy tắc khởi tạo khác nhau và VC++ vẫn thực hiện các quy tắc đó. [báo cáo lỗi] (http://connect.microsoft.com/VisualStudio/feedback/details/746973/incorrect-c-11-value-initialization-for-type-with-implicitly-declared-but-non-trivial-default -constructor) – bames53

+0

Tôi mất một chút thời gian để mò mẫm điều này, nhưng, vâng, thực tế là các ctors ngầm/ngầm định có thể gọi một ctor cơ sở không ngầm là chìa khóa. +1 từ tôi –

5

T có thể không có hàm tạo mặc định rõ ràng, nhưng nó có thể xuất phát từ U, và/hoặc có thành viên thuộc loại lớp V.

+0

Mặc dù vậy, cách trình xây dựng đó có thể thay đổi đối tượng khi nó đã được khởi tạo bằng không? –

+0

Tôi không chắc chắn ý của bạn là "thay đổi đối tượng". Để thay đổi một cái gì đó, trước tiên nó phải có một giá trị, sau đó thay đổi thành một số giá trị khác. Một hàm tạo không thay đổi bất cứ điều gì, nó thiết lập giá trị ban đầu. –

+0

Ah - khi nó nói nó là zero-initialized, nó không phải là điều tương tự như 'Foo * foo = 0'? –

4
struct S { 
    int a, b; 
    S() : b(10) {} 
}; 

struct T { 
    S s; 
}; 

int main() { 
    S s{}; 
    T t{}; 
} 

t là giá trị được khởi tạo và T không có hàm tạo do người dùng cung cấp. Tuy nhiên, constructor mặc định được khai báo ngầm của T không phải là tầm thường.

s cũng là giá trị được khởi tạo nhưng S có một hàm tạo do người dùng cung cấp.

s.a sẽ có giá trị không xác định. nhưng t.s.a bằng 0 do khởi tạo số không đứng trước lời gọi của hàm tạo mặc định.Cả hai s.bt.s.b đều được đặt thành giá trị 10.

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