2015-02-08 14 views
5

Tôi đang sử dụng Visual C++ 2013. Khi lớp là tổng hợp, nó được khởi tạo bằng không. Khi nó không phải là tổng hợp, nó dường như được khởi tạo mặc định và không xác định. Tại sao vậy?C++ 14 Khởi tạo đồng bộ trên một không tổng hợp

#include <iostream> 

using namespace std; 

class Test_1 
{ 
public: 
    int i; 
    void f(){}; 
}; 

class Test_2 
{ 
public: 
    int i; 
    virtual void f(){}; 
}; 

int main() 
{ 
    Test_1 t1{}; 
    Test_2 t2{}; 

    cout<<t1.i<<endl; //0 
    cout<<t2.i<<endl; //-858993460 

    getchar(); 
} 
+3

Trình biên dịch và phiên bản nào? '{}' nên khởi tạo giá trị cho non-aggregates và 't2.i' phải được khởi tạo bằng 0 vì nó không có hàm tạo do người dùng cung cấp. –

+0

Điều này gây ra MSVC được lưu trữ trên [rextester] (http://rextester.com/runcode) để treo và sau đó cung cấp cho rác tương tự. Cùng một điều với [trình biên dịch trực tuyến MSVC] khác (http://webcompiler.cloudapp.net/). Tôi ngửi thấy một lỗi. –

Trả lời

4

Nếu trình biên dịch của bạn đang làm việc này, nó bị hỏng.

[dcl.init.list]/p3 (tất cả dấu ngoặc kép là từ N4140):

List-khởi của một đối tượng hoặc tài liệu tham khảo của loại T được định nghĩa như sau:

  • Nếu T là tổng hợp, việc khởi tạo tổng hợp được thực hiện (8.5.1).
  • Nếu không, nếu danh sách bộ khởi tạo không có phần tử và T là loại lớp có hàm tạo mặc định, đối tượng là được khởi tạo giá trị.
  • [...]

[dcl.init]/p8:

Để 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) không có hàm tạo mặc định (12.1) hoặc hàm tạo mặc định là do người dùng cung cấp hoặc xóa, sau đó đối tượng được khởi tạo mặc định;
  • nếu T là một (có thể cv-đủ điều kiện) kiểu lớp mà không có một constructor mặc định người dùng cung cấp hoặc xóa, sau đó đối tượng là zero-khởi tạo và các khó khăn về ngữ nghĩa cho mặc định-khởi được kiểm tra, và nếu T có non-tầm thường mặc định hàm tạo, đối tượng được khởi tạo mặc định;
  • 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 không được khởi tạo.

Test_2 không phải là một tổng hợp, vì vậy t2 cần phải có được giá trị khởi tạo. Đổi lại, vì hàm tạo mặc định của Test_2 không do người dùng cung cấp, t2 được cho là không được khởi tạo đầu tiên (gây ra t2.i để được khởi tạo là 0), và sau đó hàm khởi tạo mặc định được chạy.

+4

Việc khởi tạo giá trị của các lớp không tầm thường thực sự bị phá vỡ trong VC++, và luôn luôn như vậy. Đáng buồn thay, không có sửa chữa trong tầm nhìn, mặc dù bản chất cơ bản cần thiết của ngữ nghĩa khởi tạo. [Ở đây] (https://connect.microsoft.com/VisualStudio/feedback/details/746973/không đúng-c-11-value-initialization-for-type-với-ngầm-tuyên bố-nhưng-không-tầm thường-mặc định-constructor) là một trong các báo cáo lỗi _many_ gửi, tất cả đóng như 'trì hoãn' mà tôi đã thấy. [Trong một số trường hợp, thậm chí không khởi tạo tổng hợp là chính xác.] (Https://connect.microsoft.com/VisualStudio/Feedback/Details/956553) – ildjarn

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