Các cụm từ sau có nghĩa gì trong C ++:
không khởi tạo,
khởi tạo mặc định và
khởi tạo giá trị
Nhà phát triển C ++ nên biết gì về họ?
Các cụm từ sau có nghĩa gì trong C ++:
không khởi tạo,
khởi tạo mặc định và
khởi tạo giá trị
Nhà phát triển C ++ nên biết gì về họ?
Câu trả lời:
Một điều cần nhận ra là 'khởi tạo giá trị' là mới với tiêu chuẩn C ++ 2003 - nó không tồn tại trong tiêu chuẩn gốc năm 1998 (tôi nghĩ đó có thể là sự khác biệt duy nhất không chỉ là làm rõ). Xem câu trả lời của Kirill V. Lyadvinsky cho các định nghĩa trực tiếp từ tiêu chuẩn.
Xem câu trả lời trước này về hành vi operator new
để biết chi tiết về hành vi khác nhau của các loại khởi tạo này và khi chúng khởi động (và khi chúng khác nhau từ c ++ 98 đến C ++ 03):
Điểm chính của câu trả lời là:
Đôi khi, bộ nhớ được trả về bởi toán tử mới sẽ được khởi tạo và đôi khi, bộ nhớ sẽ không phụ thuộc vào loại bạn mới cập nhật là POD hay nếu đó là lớp chứa các thành viên POD và đang sử dụng hàm 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: không và mặc định
- Trong C ++ 2003, loại khởi tạo thứ 3, khởi tạo giá trị đã được thêm vào.
Để nói rằng ít nhất, nó khá phức tạp và khi các phương pháp khác nhau phát huy tác dụng.
Một điều chắc chắn cần lưu ý là MSVC tuân theo các quy tắc C ++ 98, ngay cả trong VS 2008 (VC 9 hoặc cl.exe phiên bản 15.x).
Đoạn mã sau đây cho thấy MSVC và Digital Mars tuân theo quy tắc C ++ 98, trong khi GCC 3.4.5 và Comeau tuân theo quy tắc C ++ 03:
#include <cstdio>
#include <cstring>
#include <new>
struct A { int m; }; // POD
struct B { ~B(); int m; }; // non-POD, compiler generated default ctor
struct C { C() : m() {}; ~C(); int m; }; // non-POD, default-initialising m
int main()
{
char buf[sizeof(B)];
std::memset( buf, 0x5a, sizeof( buf));
// use placement new on the memset'ed buffer to make sure
// if we see a zero result it's due to an explicit
// value initialization
B* pB = new(buf) B(); //C++98 rules - pB->m is uninitialized
//C++03 rules - pB->m is set to 0
std::printf( "m is %d\n", pB->m);
return 0;
}
int
, nhưng m()
trên giá trị dòng thứ ba khởi tạo m. Quan trọng nếu bạn thay đổi int m;
thành B m;
. :)
A
và C
không được sử dụng trong ví dụ này (chúng được chuyển từ câu trả lời được liên kết khác). Mặc dù C ++ 98 và C ++ 03 sử dụng thuật ngữ khác nhau khi mô tả cách thức A
và C
được xây dựng, kết quả là giống nhau trong cả hai tiêu chuẩn. Chỉ có struct B
kết quả trong hành vi khác nhau.
struct C { C() : m() {}; ~C(); B m; };
, thì bạn sẽ m.m
là 0. Nhưng nếu nó sẽ khởi tạo mặc định m
như bạn nói C ++ 03, thì m.m
nó sẽ không được khởi tạo như trong C ++ 98.
C ++ 03 Tiêu chuẩn 8,5 / 5:
Để không khởi tạo một đối tượng thuộc loại T có nghĩa là:
- nếu T là loại vô hướng (3.9), thì đối tượng được đặt thành giá trị 0 (không) được chuyển đổi thành T;
- nếu T là loại lớp không liên kết, mỗi thành viên dữ liệu phi tập trung và mỗi tiểu dự án lớp cơ sở là không khởi tạo;
- nếu T là loại kết hợp, thành viên dữ liệu được đặt tên đầu tiên của đối tượng sẽ không được khởi tạo;
- nếu T là một kiểu mảng, mỗi phần tử được khởi tạo bằng không;
- nếu T là loại tham chiếu, không có khởi tạo nào được thực hiện.Để khởi tạo mặc định một đối tượng thuộc loại T có nghĩa là:
- nếu T là loại lớp không phải POD (mệnh đề 9), hàm tạo mặc định cho T được gọi (và khởi tạo được định dạng sai nếu T không có hàm tạo mặc định có thể truy cập được);
- nếu T là một kiểu mảng, mỗi phần tử được khởi tạo mặc định;
- nếu không, đối tượng là không khởi tạo.Để khởi tạo giá trị một đối tượng thuộc loại T có nghĩa là:
- nếu T là loại lớp (mệnh đề 9) với hàm tạo do người dùng khai báo (12.1), thì hàm tạo mặc định cho T được gọi (và khởi tạo không được định dạng nếu T không có hàm tạo mặc định có thể truy cập);
- nếu T là loại lớp không liên kết mà không có hàm tạo do người dùng khai báo, thì mọi thành viên dữ liệu không tĩnh và thành phần lớp cơ sở của T đều được khởi tạo giá trị;
- nếu T là một kiểu 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 khởi tạoMột chương trình yêu cầu khởi tạo mặc định hoặc khởi tạo giá trị của một thực thể của kiểu tham chiếu không được định dạng đúng. Nếu T là loại đủ điều kiện cv, phiên bản không đủ tiêu chuẩn của cv được sử dụng cho các định nghĩa về khởi tạo không, khởi tạo mặc định và khởi tạo giá trị.