如何启动和更改数组作为结构的成员变量?

时间:2015-10-30 08:50:19

标签: c++ arrays structure

例如,

struct Student
{
std::string name;
int scores[];
};

这甚至合法吗?如果是这样,我如何将一个实际值放到数组中。在这个程序中,数组的长度可以是任何正整数。它会是这样的吗?

Student s;
s.scores = int scores[length]

5 个答案:

答案 0 :(得分:2)

  

这甚至合法吗?

没有

让自己轻松自如,并使用std::vector

或者你可以通过存储指针和大小来模仿std::vector,如SingerOfTheFall的回答所示。

如果您知道scores将始终使用相同数量的元素,则应使用std::array或原始静态数组,如下所示:

int scores[length]; // 'length' is a constant expression

现在你无法改变数组的大小。

答案 1 :(得分:2)

存储指向数组的指针,该数组的大小应该足够了:

struct Student
{
    void initializeScores(int size)
    {
        scores = new int[size]{0};
        scoresSize = size;
    }

    std::string name;
    int * scores;
    int scoresSize;
};

不要忘记delete[]数组。最好的方法是用构造函数和析构函数编写一个合适的类;根据{{​​3}},您还应该定义一个复制构造函数和赋值运算符(可能还有一个移动构造函数和一个移动赋值运算符),如:

class Student
{
public:
    Student(int scoresSize)
        : scoresSize(scoresSize)
        , scores(new int[scoresSize]{10})
    {
    }

    ~Student()
    {
        delete[] scores;
    }

    //copy constructor
    Student( const Student & other )
        : scoresSize(other.scoresSize)
        , scores(new int[scoresSize])
    {
        memcpy(scores, other.scores, sizeof(int) * scoresSize);
    }

    //move constructor
    Student( Student && other)
        : scoresSize(other.scoresSize)
        , scores( other.scores )
    {
        other.scores = nullptr;
    }

    //assignment operator
    Student & operator=( const Student & other )
    {
        scoresSize = other.scoresSize;
        scores = new int[scoresSize];
        memcpy(scores, other.scores, sizeof(int) * scoresSize);
        return *this;
    }

    //move assignment operator
    Student & operator=( Student && other )
    {
        scoresSize = other.scoresSize;
        delete[] scores;
        scores = other.scores;
        other.scores = nullptr;
        return *this;
    }

private:
    std::string name;
    int scoresSize;
    int * scores;
};

或者您可以使用rule of three代替scores的原始指针。

答案 2 :(得分:1)

int scores []是一个默认大小为0的arrary。不幸的是,你不能改变它的大小,更不用说添加新项了。为了简化生活,请在必要时使用poninter创建动态数组,或者只使用向量。

答案 3 :(得分:1)

如果要使用数组内部结构,则必须知道长度并指定

struct Student
{
std::string name;
int scores[3];
};

Student j = {"Jhon", {10, 11, 12}};

如果您不知道长度,则必须使用std::vector而不是数组

struct Student
{
std::string name;
std::vector scores;
};

Student j = {"Jhon", {10, 11, 12}};
Student s = {"Smith", {10, 11, 12,13}};

答案 4 :(得分:1)

由于您无法使用std::vector,我认为您也无法使用std::unique_ptr之类的内容,这意味着您必须自己进行一些内存管理。虽然这没关系,但是一旦你不受家庭作业限制,你应该更喜欢使用该语言提供的工具,让你的生活更轻松,你的程序更健壮。

有了这个,你可以在这里找到你想要的东西:

struct Student
{
    Student()
        : scores(nullptr)
        , scoresSize(0)
    {
    }

    ~Student()
    {
        delete[] scores;
    }

    void initializeScores(int size)
    {
        scores = new int[size]{0};
        scoresSize = size;
    }

    std::string name;
    int* scores;
    int scoresSize;
};

如果您在构建Student对象时知道所需的分数,则可以做得更好:

struct Student
{
    Student(std::string n, int size)
        : name(n)
        , scoresSize(size)
    {
        scores = new int[size]{0};
    }

    ~Student()
    {
        delete[] scores;
    }

    std::string name;
    int* scores;
    int scoresSize;
};

只是为了挑剔,Student类应遵循3的规则或可能禁用复制构造函数和复制赋值,以避免内存泄漏和双重删除(即崩溃)。另请注意,在构造函数中调用new就像我们在这里做的那样,在这种简单程序中您不太可能遇到的某些情况下可能会泄漏内存。首选std::unique_ptrstd::make_unique可让问题自动消失。