[英]How are you supposed to initialize an Array attribute that I don't know the contents of?
我的代碼中指定了以下 class 。
class Foo{
private:
int myInt;
Bar myList[10];
public:
Foo(){
myInt = 0;
}
void addBar(Bar b){
this->myList[myInt] = b;
myInt ++;
}
};
我收到錯誤
Foo 的構造函數必須顯式初始化沒有默認構造函數的成員 myList。
問題是直到運行時我才知道該列表將包含什么,因為用戶將Bar
對象添加到列表中 - 而我的Bar
對象沒有默認值,需要指定它們。
我應該如何在那里初始化該變量?
這是 class Bar
的定義
class Bar{
private:
std::string name;
int number;
public:
Bar(std::string name, int number){
name = name;
number = number;
};
這是我在main()
上所做的
int main(){
Bar b("Red",1);
Foo f();
f.addBar(b)
return 0;
}
好吧,我建議只使用std::vector<Bar>
而不是嘗試使用原始數組。 關於數組的事情是你不能離開它的任何對象未構造。 如果您真的想知道如何自己實現這一點,您可以首先在數組中使用不同的類型,不需要任何初始化,然后根據需要重用 memory 來創建和銷毀對象。
“不同類型”是std::aligned_storage_t
。 方便的是,頁面上的示例正是我們想要的。
// template<class T, std::size_t N>
// class static_vector
// T = Bar; N = 10
class Foo {
// properly aligned uninitialized storage for 10 Bars
std::aligned_storage_t<sizeof(Bar), alignof(Bar)> data[10];
std::size_t size = 0;
public:
// compiler-provided default constructor does not initialize data
Foo() = default;
void addBar(Bar b) {
if(size >= 10) throw std::bad_alloc{}; // possible error handling
// reuse uninitialized memory for a Bar
new(&data[size]) Bar(std::move(b));
size++; // if constructor can throw, this must be after the constructor!
}
Bar const &operator[](std::size_t pos) const noexcept {
return *std::launder(reinterpret_cast<Bar const*>(&data[pos]));
}
Bar &operator[](std::size_t pos) noexcept {
return *std::launder(reinterpret_cast<Bar*>(&data[pos]));
}
void popBar() {
if(size <= 0) return; // or whatever
operator[](--size).~Bar();
}
// Have to remember to clean up!
~Foo() {
while(size) popBar();
}
// all the other special functions need to be custom...
// we even have to handle cleanup!
Foo(Foo const &other) {
try {
for(std::size_t i = 0; i < other.size; i++) addBar(other[i]);
} catch(...) {
while(size) popBar();
throw;
}
}
Foo(Foo &&other) {
try {
for(std::size_t i = 0; i < other.size; i++) addBar(std::move(other[i]));
} catch(...) {
while(size) popBar();
throw;
}
}
Foo &operator=(Foo const &other) {
while(size > other.size) popBar();
std::size_t i = 0;
for(; i < size && i < other.size; i++) operator[](i) = other[i];
for(; i < other.size; i++) addBar(other[i]);
return *this;
}
Foo &operator=(Foo &&other) {
while(size > other.size) popBar();
std::size_t i = 0;
for(; i < size && i < other.size; i++) operator[](i) = std::move(other[i]);
for(; i < other.size; i++) addBar(std::move(other[i]));
return *this;
}
// should also add a way to check size, maybe clear, etc.
};
此外,您的Bar
應該這樣寫:
class Bar {
std::string name;
int number;
public:
Bar(std::string name, int number) : name(std::move(name)), number(number) { }
};
和你的main
int main() {
Foo f; // Foo f(); declares a function!
f.addBar({"Red", 1});
return 0;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.