分配在堆栈上的结构的C ++向量

时间:2019-07-06 09:33:53

标签: c++

如果我们有一个结构指针MyInfo*的向量(分配在堆上)。然后我们可以检查vec[i] == NULL来知道vec[i]中是否有一个结构,像这样,if (vec[i] != NULL) //then do some processing

但是,如果我们在堆栈上而不是在堆上分配MyInfo,则我们有vector<MyInfo>,如下所示。我猜每个vec [i]是由struct默认构造函数初始化的。如何检查vec [i]是否包含类似于上述NULL指针大小写的非空结构,例如if (vec[i] contains valid struct) //then do some processing

我的代码在下面

#include <iostream>     // std::cout
#include <string>
#include <vector>

using namespace std;

struct MyInfo {
    string name;
    int age;
};

int main () {
    vector<MyInfo> vec(5);
    cout << "vec.size(): " << vec.size() << endl;
    auto x = vec[0];
    cout << x.name << endl; //this print "" empty string
    cout << x.age << endl; //this print 0

    return 0;
}

1 个答案:

答案 0 :(得分:2)

您可以使用一些选项。第一个也是最简单的方法是为结构的每个变量(或其中一个)定义一个值,这将指出该结构尚未初始化。在这种情况下,age应该大或等于0,以便在逻辑上是直的。因此,您可以将其初始化为-1,如下所示:

struct MyInfo {
    string name;
    int age = -1;
};
// Or
struct MyInfo {
    string name;
    int age;
    MyInfo() : name(""), age(-1) {} // Use constructor
};

现在,在您的主要功能中,它将在age中打印值-1。此外,您也可以看到name变量的空白作为其符号。

另一种方法可能是使用标志和获取/设置操作来指示何时初始化变量:

struct MyInfo {
private:
    std::string _name;
    int _age;
    bool age_initialize = false;
    bool name_initialize = false;

public:
    void name(const std::string &name_p) { _name = name_p; name_initialize = true; }
    void age(int age_p) { _age = age_p; age_initialize = true; }
    void init(int age_p, const std::string &name_p) { age(age_p); name(name_p); }
    bool is_initialize() { return name_initialize && age_initialize; }
    int age() { return _age; }
    std::string name() { return _name; }
};

int main() {
    std::vector<MyInfo> vec(5);
    std::cout << "vec.size(): " << vec.size() << std::endl;

    auto x = vec[0];
    std::cout << x.is_initialize() << std::endl; //this print 0
    std::cout << x.name() << std::endl; //this print "" empty string
    std::cout << x.age() << std::endl; //this print 0

    return 0;
}

如果尚未初始化int age()函数的std::string name(),则还可以引发异常:

struct MyInfo {
private:
    /* ... */

public:
    /* ... */
    int age() {
        if (!age_initialize) throw std::runtime_error("Please initialize age first.");
        return _age;
    }
    std::string name() {
        if (!name_initialize) throw std::runtime_error("Please initialize name first.");
        return _name;
    }
};