Bối cảnh: Tôi đang ở trong một môi trường mã lớn, nơi thứ tự không xác định trong đó các nhà xây dựng toàn cầu đang chạy là có vấn đề. Vì vậy, tôi có một lớp tùy chỉnh được thiết kế để trì hoãn khởi tạo cho đến khi sử dụng lần đầu tiên. Tất cả phép thuật của nó xảy ra bên trong toán tử * và toán tử-> hàm; chúng là thứ duy nhất được xác định. Nó cũng lưu trữ một số trạng thái trong chính nó, để có sẵn cho chức năng khởi tạo tự động. Tất nhiên, trạng thái đó là POD, để toàn bộ lớp là POD, để nó có thể được thiết lập hoàn toàn trước khi mã của mọi người bắt đầu chạy, để mọi mã ở mọi nơi đều có thể sử dụng tất cả các hình cầu ở mọi nơi, mà không sợ chưa được thiết lập.C++ 11: Một toán tử gán có ngăn chặn một loại khỏi POD và do đó được khởi tạo toàn cục không?
Một thời gian trở lại một người nào đó đã thêm một toán tử gán riêng, không bao giờ được xác định, để loại đó sẽ không bao giờ được gán cho (nó chưa được thiết kế để thay đổi bao giờ). Bây giờ một người khác nói rằng lớp học bị phá vỡ vì nó không phải là POD. Nếu thay vì nó được khai báo nhưng không được xác định, tôi tuyên bố nó là "= xóa", tôi nghĩ rằng đó là bằng cách nào đó tốt hơn. Và thực sự, với thay đổi đó, tiêu chuẩn :: is_pod <> :: giá trị trả về đúng cho loại.
Nhưng liệu toán tử gán có ngăn chặn loại khỏi POD không? Tôi nghĩ rằng các yêu cầu chỉ là nó phải chỉ có các thành viên dữ liệu công khai, không có các phương thức ảo, và không có hàm tạo hoặc hàm hủy.
Và nhiều hơn nữa cho vấn đề của tôi: sự hiện diện của một toán tử gán không được định nghĩa có ngăn không cho khởi tạo lớp tại thời gian khởi tạo toàn cục, cùng với tất cả các POD toàn cầu khác không?
Giảm dụ:
struct LazyString {
const char *c_str;
bool has_been_inited;
string *lazy_str_do_not_use_directly;
string &operator*() { return *get(); }
string *operator->() { return get(); }
private:
string *get() {
// The real code uses a mutex, of course, to be thread-safe.
if (!has_been_inited) {
lazy_str_do_not_use_directly = new string(c_str);
has_been_inited = true;
}
return lazy_str_do_not_use_directly;
}
// Does this make the class non-POD?
// If so, does that mean that global variables of this type
// will not be initialized at global-initialization time, that wonderful
// moment in time where no code has yet been run?
void operator=(const LazyString&);
// If I do this instead, it breaks C++03 compatibility, but is this somehow better?
void operator=(const LazyString&) = delete;
};
LazyString lazy = { "lazy" };
int main(int argc, char *argv[]) {
std::cout << *lazy;
}
Pha chế quản lý bộ nhớ heap của riêng bạn gần như không bao giờ là ý tưởng hay. Tại sao bạn nghĩ rằng bạn cần điều này? (Ý bạn là thực hiện s.th. tương tự như [copy-on-write] (http://stackoverflow.com/questions/12199710/legality-of-cow-stdstring-implementation-in-c11)) –
Bạn là gây nhầm lẫn POD-Ness và khởi tạo tĩnh. Không phụ thuộc vào nhau. –
Vì tất cả các thành viên dữ liệu đều hiển thị công khai, khai báo đó tạo nên POD, có. ** LƯU Ý: ** Bạn sẽ gặp phải các tác dụng phụ không mong muốn liên quan đến 'chuỗi mới (c_str);' trong khởi tạo _lazy của bạn, khi sao chép/gán kiểu POD này xung quanh. –