Tôi rất bối rối về giá trị- & mặc định- & không khởi tạo. và đặc biệt là khi họ bắt đầu sử dụng các tiêu chuẩn khác nhau C ++ 03 và C ++ 11 (và C ++ 14 ).
Tôi đang trích dẫn và cố gắng mở rộng một câu trả lời thực sự tốt Value- / Default- / Zero- Init C ++ 98 và C ++ 03 ở đây để làm cho nó tổng quát hơn vì nó sẽ giúp rất nhiều người dùng nếu ai đó có thể giúp điền vào những khoảng trống cần thiết để có cái nhìn tổng quan tốt về điều gì xảy ra khi nào?
Tóm lại, toàn bộ thông tin chi tiết bằng các ví dụ:
Đôi khi bộ nhớ được trả về bởi toán tử mới sẽ được khởi tạo và đôi khi nó sẽ không phụ thuộc vào việc loại bạn mới tải lên là POD (dữ liệu cũ thuần túy) hay là một lớp có chứa các thành viên POD và đang sử dụng phương thức khởi tạo mặc định do trình biên dịch tạo.
- Trong C ++ 1998 có 2 loại khởi tạo: zero- và mặc định-khởi
- Trong C ++ 2003, kiểu khởi tạo thứ 3, khởi tạo giá trị đã được thêm vào.
- Trong C ++ 2011 / C ++ 2014 chỉ khởi tạo danh sách được thêm vào và các quy tắc cho khởi tạo value- / default- / zero đã thay đổi một chút.
Giả định:
struct A { int m; };
struct B { ~B(); int m; };
struct C { C() : m(){}; ~C(); int m; };
struct D { D(){}; int m; };
struct E { E() = default; int m;}; /** only possible in c++11/14 */
struct F {F(); int m;}; F::F() = default; /** only possible in c++11/14 */
Trong trình biên dịch C ++ 98, điều sau sẽ xảy ra :
new A- giá trị không xác định (Alà POD)new A()- không khởi tạonew B- cấu trúc mặc định (B::mchưa được khởi tạo,Bkhông phải POD)new B()- cấu trúc mặc định (B::mchưa được khởi tạo)new C- cấu trúc mặc định (C::mkhông được khởi tạo,Ckhông phải là POD)new C()- cấu trúc mặc định (C::mđược khởi tạo bằng 0)new D- cấu trúc mặc định (D::mchưa được khởi tạo,Dkhông phải POD)new D()- cấu trúc mặc định? (D::mchưa được khởi tạo)
Trong trình biên dịch tuân theo C ++ 03, mọi thứ sẽ hoạt động như vậy:
new A- giá trị không xác định (Alà POD)new A()- value-initializeA, là không khởi tạo vì nó là POD.new B- khởi tạo mặc định (B::mkhông khởi tạo,Bkhông phải POD)new B()- giá trị khởi tạoBkhông khởi tạo tất cả các trường vì ctor mặc định của nó là trình biên dịch được tạo ra trái ngược với do người dùng xác định.new C- default-khởi tạoC, gọi ctor mặc định. (C::mkhông được khởi tạo,Ckhông phải POD)new C()- giá trị khởi tạoC, gọi ctor mặc định. (C::mđược khởi tạo bằng 0)new D- cấu trúc mặc định (D::mchưa được khởi tạo,Dkhông phải POD)new D()- giá trị khởi tạo D? , gọi là ctor mặc định (D::mchưa được khởi tạo)
Giá trị nghiêng và? là những điểm không chắc chắn, vui lòng giúp sửa lỗi này :-)
Trong trình biên dịch tuân theo C ++ 11, mọi thứ sẽ hoạt động như vậy:
??? (xin vui lòng giúp đỡ nếu tôi bắt đầu ở đây, nó vẫn sẽ sai)
Trong một trình biên dịch tuân thủ C ++ 14, mọi thứ sẽ hoạt động như vậy: ??? (Xin vui lòng giúp đỡ nếu tôi bắt đầu ở đây, nó vẫn sẽ sai )
new A- default-khởi tạoA, gen biên dịch. ctor, (leavsA::muninitialized) (Alà POD)new A()- giá trị khởi tạoA, là không khởi tạo kể từ 2. điểm trong [dcl.init] / 8new B- default-khởi tạoB, gen biên dịch. ctor, (leavsB::muninitialized) (Bkhông phải POD)new B()- giá trị khởi tạoBkhông khởi tạo tất cả các trường vì ctor mặc định của nó là trình biên dịch được tạo ra trái ngược với do người dùng xác định.new C- default-khởi tạoC, gọi ctor mặc định. (C::mkhông được khởi tạo,Ckhông phải POD)new C()- giá trị khởi tạoC, gọi ctor mặc định. (C::mđược khởi tạo bằng 0)new D- mặc định khởi tạoD(D::mchưa được khởi tạo,Dkhông phải POD)new D()- giá trị khởi tạoD, gọi ctor mặc định (D::mchưa được khởi tạo)new E- default-khởi tạoE, gọi comp. gen. ctor. (E::mchưa được khởi tạo, E không phải POD)new E()- giá trị khởi tạoE, khởi tạo bằng khôngEkể từ 2 điểm trong [dcl.init] / 8 )new F- default-khởi tạoF, gọi comp. gen. ctor. (F::mchưa được khởi tạo,Fkhông phải POD)new F()- value-khởi tạoF, khởi tạo mặc địnhFkể từ 1. point trong [dcl.init] / 8 (Fhàm ctor do người dùng cung cấp nếu nó do người dùng khai báo và không được mặc định rõ ràng hoặc bị xóa trên khai báo đầu tiên của nó. Liên kết )