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 (A
là POD)new A()
- không khởi tạonew B
- cấu trúc mặc định (B::m
chưa được khởi tạo,B
không phải POD)new B()
- cấu trúc mặc định (B::m
chưa được khởi tạo)new C
- cấu trúc mặc định (C::m
không được khởi tạo,C
khô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::m
chưa được khởi tạo,D
không phải POD)new D()
- cấu trúc mặc định? (D::m
chư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 (A
là 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::m
không khởi tạo,B
không phải POD)new B()
- giá trị khởi tạoB
khô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::m
không được khởi tạo,C
khô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::m
chưa được khởi tạo,D
không phải POD)new D()
- giá trị khởi tạo D? , gọi là ctor mặc định (D::m
chư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::m
uninitialized) (A
là 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::m
uninitialized) (B
không phải POD)new B()
- giá trị khởi tạoB
khô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::m
không được khởi tạo,C
khô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::m
chưa được khởi tạo,D
không phải POD)new D()
- giá trị khởi tạoD
, gọi ctor mặc định (D::m
chưa được khởi tạo)new E
- default-khởi tạoE
, gọi comp. gen. ctor. (E::m
chư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ôngE
kể từ 2 điểm trong [dcl.init] / 8 )new F
- default-khởi tạoF
, gọi comp. gen. ctor. (F::m
chưa được khởi tạo,F
không phải POD)new F()
- value-khởi tạoF
, khởi tạo mặc địnhF
kể từ 1. point trong [dcl.init] / 8 (F
hà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 )