Khai báo một đối tượng const trong C ++ đòi hỏi một hàm tạo mặc định do người dùng định nghĩa. Nếu tôi có một biến thành viên có thể thay đổi, tại sao không?


8

Trong C ++, để khai báo một đối tượng của một lớp có biến thành viên là const, chúng ta phải có một hàm tạo mặc định do người dùng định nghĩa. Các mã sau đây minh họa điều này.

class Some {
    int value;
};

int main() {
    // error: default initialization of an object of const type 'const Some'
    //        without a user-provided default constructor
    const Some some;

    return 0;
}

Tuy nhiên, nếu một biến thành viên thuộc sở hữu của một lớp đủ điều kiện là có thể thay đổi, trình biên dịch sẽ không báo cáo bất kỳ lỗi nào. Để tham khảo, tôi biên dịch bằng cách sử dụng lệnh clang++ -std=c++17 -stdlib=libc++ helloworld.cpp -o helloworld.out --debug. Tôi tự hỏi nếu kết quả này là do lỗi trong trình biên dịch hoặc theo cú pháp được xác định trong ngôn ngữ C ++.

class Some {
    mutable int value;
};

int main() {
    const Some some;

    return 0;
}



2
mutablelà loại đối lập với const. Tại sao bạn mong đợi hiệu ứng tương tự?
idclev 463035818

2
Vì nó không có ý nghĩa gì khi khởi tạo một đối tượng thành a const, nghĩa là nó không thể thay đổi và nó có các giá trị chưa được khởi tạo, không sử dụng loại mã này và đó là lý do tại sao nó bị cấm. Khi bạn sử dụng mutabletừ khóa - điều đó có nghĩa là giá trị có thể được thay đổi sau đó, do đó mã có thể được sử dụng theo cách có thể dự đoán được.
Moshe Gottlieb

4
@Phải không? OP đã biết rằng đoạn mã đầu tiên không được định dạng đúng, họ tự hỏi tại sao clang chấp nhận lần thứ hai mà không có bất kỳ chẩn đoán nào.
Bob__

Câu trả lời:


2

Viết lại nhận xét của tôi như một câu trả lời, hy vọng nó có thể giúp được ai đó.

Không có nghĩa gì khi khai báo một đối tượng const nếu nó không được khởi tạo ở một số dạng.
Hãy xem xét các mã sau đây:

    const int x;

clang nói : error: default initialization of an object of const type 'const int'.
gcc sẽ nói:error: uninitialized const ‘x’ [-fpermissive]

Logic đằng sau điều này là không có ý nghĩa trong loại khai báo này.
Giá trị của xkhông bao giờ có thể thay đổi, và do đó mã này sẽ không thể đoán trước được như xđược ánh xạ tới bộ nhớ chưa được khởi tạo.
Trong ví dụ của bạn, việc thêm từ khóa mutablevào valuecó nghĩa là mặc dù Somethể hiện là hằng số khi được khai báo là:

    const Some some;

Vẫn có thể thay đổi valuesau đó.
Ví dụ:

    some.value = 8;

Điều này có nghĩa là có thể sử dụng mã này theo cách có thể dự đoán được, vì valuecó thể được đặt sau và không có hằng số chưa được khởi tạo.


Nếu vậy, chúng ta có thể xác định rằng có một lỗi trong gcc không? Khi tôi biên dịch chương trình với gcc, nó báo lỗi mặc dù các biến thành viên có thể thay đổi.
jinbeom hong

1
Xin lỗi @jinbeomhong - Tôi không biết. Tôi chỉ có thể đoán nhóm gcc diễn giải các tiêu chuẩn khác nhau.
Moshe Gottlieb

Dù sao, tôi chỉ cần những lý do hợp lý để hiểu rằng những kết quả này đang đến, và để tuân theo logic của bạn, tôi nghĩ clang ++ đã đánh giá một cách hợp lý cú pháp. Cảm ơn.
jinbeom hong
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.