【问题标题】:How to initiate and change an array as a member variable of a structure?如何初始化和更改数组作为结构的成员变量?
【发布时间】:2015-10-30 08:50:19
【问题描述】:

例如,

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

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

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

【问题讨论】:

  • 改用向量。
  • @SingerOfTheFall 我不允许在这个程序中使用向量
  • Array in C struct的可能重复

标签: c++ arrays structure


【解决方案1】:

这合法吗?

没有。

让自己轻松一点,使用std::vector

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

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

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

现在您无法更改数组的大小。

【讨论】:

  • 这个程序不能使用向量
【解决方案2】:

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

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

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

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

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;
};

或者您可以只使用std::unique_ptr 而不是指向scores 的原始指针。

【讨论】:

  • 不要盲目地说“别忘了delete[]”。解释如何使用构造函数和析构函数来帮助确保进行清理。
  • @NikBougalis,感谢您的注意,但是我无法快速输入 ,因此我在编辑答案时将该注释添加为占位符。
  • 在这种情况下,您应该遵循 3 或 5 的规则。或者将原始指针替换为 unique_ptr 并遵循 0 的规则。我认为在建议使用原始 @ 时应该提到这一点987654329@/delete.
【解决方案3】:

如果你想在结构中使用数组,你必须知道长度并指定它

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】:

    由于您不能使用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 让问题自动消失。

    【讨论】:

      【解决方案5】:

      int scores[] 是一个默认大小为 0 的数组。不幸的是,您无法更改其大小,更不用说添加新项目了。为方便起见,如有必要,请使用 poninter 创建动态数组或仅使用 vector 代替。

      【讨论】:

      • 不,int scores[] 不是指针,它是一个大小不一的数组,在此处使用的 C++ 中无效。
      • 对不起,int score[] 是“类似”常量 int 指针,您可以编译它而不会出错,但不能为其分配任何值。请使用 int 指针或向量来简化生活。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-22
      • 1970-01-01
      • 1970-01-01
      • 2018-03-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多