2011-08-16 44 views
8

Tôi đã luôn nghĩ rằng việc tạo một đối tượng mới sẽ luôn gọi hàm khởi tạo mặc định trên một đối tượng và liệu hàm tạo có được trình biên dịch rõ ràng hoặc tự động tạo ra không có sự khác biệt nào. Theo this highly regarded answer cho một câu hỏi khác nhau, điều này đã thay đổi một cách tinh tế giữa C++ 98 và C++ 03 và hiện đang làm việc như vậy:Sự khác biệt giữa mặc định khởi tạo và giá trị khởi tạo trong C++ 03?

struct B { ~B(); int m; }; // non-POD, compiler generated default ctor 
new B; // default-initializes (leaves B::m uninitialized) 
new B(); // value-initializes B which zero-initializes all fields since its default ctor is compiler generated as opposed to user-defined. 

Bất cứ ai có cho tôi biết:

  1. Tại sao tiêu chuẩn đã thay đổi, tức là những lợi thế nào mà điều này đưa ra hoặc những gì bây giờ có thể đã không có trước đó;
  2. Các thuật ngữ "default-initialize" và "value-initialize" đại diện cho điều gì?
  3. Phần liên quan của tiêu chuẩn là gì?
+0

Phần liên quan của tiêu chuẩn C++ 11 mới là 8.5 ("Khởi tạo") điều khoản 5,6,7. –

+0

Có thể nó cung cấp cho mọi người tùy chọn sử dụng ctor mặc định hay không. Trong phiên bản cũ của C++, các dấu ngoặc thường bị mất khi không có tham số. Vì vậy, việc có các dấu ngoặc trên tùy chọn mới sẽ ảnh hưởng đến mã cũ hơn. – QuentinUK

+0

Tôi sẽ không gọi nó là thay đổi, mà là thay đổi. Nó ít nhất cũng có ý nghĩa trong bối cảnh của ví dụ std :: map nơi các giá trị được tạo bởi [] là giá trị được intialized, vì vậy ví dụ: std :: map tất cả U * được initlaized đến 0 – PlasmaHH

Trả lời

2

Tôi không biết những gì các lý do cơ bản xung quanh thay đổi (hoặc làm thế nào tiêu chuẩn trước kia), nhưng về cách nó là, về cơ bản mặc định-khởi là một trong hai cách gọi một người sử dụng constructor xác định hoặc không làm gì cả (nhiều vẫy tay ở đây: đây là đệ quy được áp dụng cho mỗi subobject, có nghĩa là subobjects với một constructor mặc định sẽ được khởi tạo, các subobjects không có constructor do người dùng định nghĩa sẽ được uninitialized).

Điều này nằm trong phạm vi chỉ trả tiền cho những gì bạn muốn triết lý của ngôn ngữ và tương thích với C trong tất cả các loại tương thích với C. Mặt khác, bạn có thể yêu cầu khởi tạo giá trị và điều này tương đương với việc gọi hàm tạo mặc định cho các đối tượng có số hoặc khởi tạo thành 0 chuyển thành loại thích hợp cho các phần còn lại của các đối tượng phụ.

Điều này được mô tả trong §8.5 Trình khởi tạo và không tầm thường để điều hướng. Các định nghĩa cho zero-khởi, mặc định-khởigiá trị khởi tạo là đoạn 5:

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

- nếu T là một loại vô hướng (3.9), đối tượng được đặt thành giá trị 0 (không) được chuyển thành T;

- nếu T là loại nhóm không phải là công đoàn, mỗi thành viên dữ liệu phi tĩnh và mỗi lớp con cấp cơ sở là zeroinitialized;

- nếu T là loại liên kết, thì tên dữ liệu đầu tiên của đối tượng89) được khởi tạo bằng 0;

- nếu T là một loại mảng, mỗi phần tử không được khởi tạo;

- nếu T là loại tham chiếu, không có khởi tạo nào được thực hiện.

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

- nếu T là một-POD phi kiểu lớp (khoản 9), các nhà xây dựng mặc định cho T được gọi là (và khởi tạo là vô hình thành nếu T không có hàm tạo mặc định có thể truy cập);

- nếu T là một loại mảng, mỗi phần tử được khởi tạo mặc định;

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

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

- nếu T là một loại lớp (khoản 9) với một constructor do người dùng khai báo (12.1), sau đó các nhà xây dựng mặc định cho T được gọi là (và việc khởi tạo bị hỏng nếu T không có hàm tạo mặc định có thể truy cập được);

- nếu T là loại không kết hợp mà không có người tạo khai báo, thì mọi thành phần dữ liệu không tĩnh và thành phần lớp cơ sở của T được khởi tạo giá trị;

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

- nếu không, đối tượng được zero-khởi

Một chương trình mà các cuộc gọi cho mặc định-khởi tạo hoặc giá trị khởi tạo của một thực thể của kiểu tham chiếu không hoàn chỉnh. Nếu T là loại có đủ điều kiện cv, phiên bản T không đủ tiêu chuẩn của T được sử dụng cho các định nghĩa này về zeroinitialization, khởi tạo mặc định và khởi tạo giá trị.

+0

Đoạn đầu tiên của bạn đã xác định hành vi của Khởi tạo mặc định là hoặc sử dụng ctor hoặc uninitialized của nó. Câu hỏi của tôi là việc giải thích các báo giá bao gồm của phần 8.5 Initializer xác định khởi tạo mặc định mà có là bước cuối cùng ... "- nếu không, đối tượng là zero-initialized". Nó dường như gợi ý rằng nếu không có ctor thì sử dụng các quy tắc của zero-initialize và để nó uninitialized. – TheChrisONeil

+0

@CBO: Trích dẫn cụ thể đó là từ C++ 03, trong C++ 11 mục cuối cùng đã thay đổi và đọc: * nếu không, không có khởi tạo nào được thực hiện *. Chìa khóa ở điểm này là những gì được viết một vài đoạn sau đó. Đối với một đối tượng không có bộ khởi tạo được cung cấp, trong C++ 03 đối tượng không được khởi tạo (trong/9), trong C++ 11 đối tượng là * mặc định khởi tạo * (/ 12).Không chắc chắn nếu điều này trả lời mối quan tâm của bạn –

+0

Làm cho tinh thần và cảm ơn cho việc theo dõi. Tôi khuyên bạn nên cập nhật bài đăng của mình ngay bây giờ bao gồm nội dung của C++ 11. – TheChrisONeil

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