mảng object trong C++ thì mỗi object đều được init bằng default ctor mà :V Lý do là vì nó sẽ được tự động hủy khi ra khỏi phạm vi của nó, mà khi hủy mảng thì nó phải gọi hàm hủy cho từng phần tử đã được khởi tạo luôn, nhưng lúc compile time làm sao biết phần tử nào sẽ được init lúc runtime mà gọi hàm hủy cho đúng. Vì vậy phải gọi hàm hủy cho tất cả các phần tử, dẫn tới khi khai báo mảng object tất cả các obj phải được khởi tạo. Chỉ với phần tử có kiểu nguyên thủy thì mới ko cần ctor/dtor thôi.
mà ở đây đã gọi ctor cho mảng san_pham
bằng {...}
là aggregate initialization :V :V trong đó nó có ghi
For a non-union aggregate, each element that is not an explicitly initialized element is initialized as follows:
- If the element has a default member initializer, the element is initialized from that initializer. (since C++11)
- Otherwise, if the element is not a reference, the element is copy-initialized from an empty initializer list.
- Otherwise, the program is ill-formed.
nghĩa là từng phần tử ko được khởi tạo tường minh thì sẽ được copy-initialized bằng empty initializer list :V :V chắc là gọi default ctor. Mà nếu default ctor được viết là product() {}
mà nếu phần tử chuỗi, tạm gọi là name
, ko phải là std::string
mà là const char*
thì name
mang giá trị rác thật, tuy có gọi default ctor nhưng default ctor ko khởi tạo const char* name
nên thành ra cũng như ko khởi tạo :V Nếu khai báo biến name
theo kiểu default member initializer const char* name{};
thì ok, default ctor sẽ khởi tạo name = 0
thì check được :V
(sao tôi thử thấy explicitly defaulted default ctor, aka viết theo kiểu product() = default;
nó lại gán 0 cho const char*
lẫn int
luôn nhỉ :V mà ko tìm thấy chỗ nào trong doc viết, chắc là ngẫu nhiên)
ồ tôi tìm ra rồi nếu class/struct product
đó là trivial thì class/struct được viết product() = default
vẫn giữ được là trivial class (trong khi product() {}
được xem là user-provided ctor, nên class này ko còn trivial nữa), nên init với empty init list nó sẽ được value initialized, sẽ zero-initialized cho từng phần tử kiểu nguyên thủy
tóm lại để chắc ăn thì viết cái default ctor cho product
đàng hoàng nữa là kiểm tra được:
class product {
public:
product() : name{}, value1{}, value2{} {}
};
hoặc nếu xài C++11 trở lên thì
class product {
public:
product() = default;
private:
<kiểu chuỗi> name{}; // xài default member initializer cho từng phần tử trong product
int value1{};
int value2{};
};
rồi check san_pham[i].name
là chuỗi trống hay là NULL là được. Với điều kiện san_pham[i]
đã khởi tạo thì name
phải ko là chuỗi trống hay NULL được :V :V