簡體   English   中英

你應該如何初始化一個我不知道其內容的 Array 屬性?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM