【问题标题】:How to pass parameters to constructor when creating an array of objects using for loop使用for循环创建对象数组时如何将参数传递给构造函数
【发布时间】:2021-07-03 07:08:49
【问题描述】:
class Student
{
    int rollNo;
    string name;

    public:
        Student(int id_of_student, string name_of_student)
        {
            rollNo = id_of_student;
            name = name_of_student;
        }
        void getStudentData()
        {
            cout<<"The name of the student with roll No. "<<rollNo<<" is "<<name<<endl;
        }
};

int main()
{
    Student *ptr = new Student[30]; // Error: no default constructor exists for class "Student"

    return 0;
}

有什么方法可以将参数传递给构造函数?

Error: no default constructor exists for class "Student"

【问题讨论】:

  • 为什么要使用new 而不是std::vector?对于后者,使用参数创建对象的问题稍微简单一些——你可以编写一个循环而不是很长的初始化列表。
  • 在这种情况下,除了 emplace_backnew 或 C++11 初始化方法之外,总是有旧的 init-Function 选项。从构造函数中删除参数(或为它们提供默认值),但还要定义一个initfunction,它做同样的事情。然后您可以在分配对象后初始化对象。如果你愿意,即使在一个循环中。

标签: c++ arrays class object


【解决方案1】:

如果我是你,我会使用std::vector。但是,如果您更喜欢坚持使用array,我将使用array 来做这件事(下面是std::vector 示例)

#include <iostream>
using namespace std;
class Student
{
    int rollNo;
    string name;

    public:
        Student(int id_of_student, string name_of_student)
        {
            rollNo = id_of_student;
            name = name_of_student;
        }
        void getStudentData()
        {
            cout<<"The name of the student with roll No. "<<rollNo<<" is "<<name<<endl;
        }
};

int main()
{
       //Student *ptr = new Student[30]; // Error: no default constructor exists for class "Student"
    Student *array[30];
    //allocates 30 objects
    for (int i = 0 ; i != 30 ; i++)
    {
        array[i] = new Student(i, "Name Array" + std::to_string(i));
    }
    //usage
    for (int i = 0 ; i != 30 ; i++)
    {
        array[i]->getStudentData();
    }

    // freeing the 10 objects
    for (int i = 0 ; i != 30 ; i++)
    {
        delete array[i];
    }

       // you may also use std::vector
    std::vector<Student> arr;
    //reserve for 30 objects
    arr.reserve(30);
    for (int i = 0 ; i != 30 ; i++)
    {
        arr.push_back( Student(i, "Name vector" + std::to_string(i))) ;
    }
    // usage
    for (Student stu: arr)
    {
        stu.getStudentData();
    }
}

【讨论】:

  • 不需要使用指针向量,你可以使用Student对象的向量
  • 完成!!感谢您再次审查:)
【解决方案2】:

按照您的要求,一个简单的方法是使用std::vector

std::vector<Student> students;
//This is optional, it prevents multiple reallocations, which is nice
students.reserve(30);
students.emplace_back(id, name);
students.push_back(Student(id, name));

但是,您可以考虑只添加一个默认构造函数。对象是否已初始化由您自己决定(我强烈建议不要添加像 bool is_initialized 这样的成员,以防您想这样做)

【讨论】:

    【解决方案3】:

    来自cppreference

    ::(可选) new (placement_params)(可选) (type) 初始化器(可选)

    如果初始值设定项是用大括号括起来的参数列表,则数组是聚合初始化的。 (C++11 起)

    你可以像这样使用可选的聚合初始化器:

    Student *ptr = new Student[3]{{1, "one"}, {2, "two"}, {3, "three"}};
    

    但是,如果您有很多学生(例如您的示例中的 30 个),那就不太舒服了。

    【讨论】:

    • 好吧,我会选择std::vector&lt;Student&gt; vec;(后跟reserve 以避免内存重新分配),然后在循环中vec.push_back(Student(i, "whatever"));。但是你问了operator new,所以我把这个例子留作参考。
    猜你喜欢
    • 1970-01-01
    • 2012-07-09
    • 2013-05-11
    • 2016-06-25
    • 2020-05-10
    • 1970-01-01
    • 2013-09-13
    • 2020-07-27
    • 1970-01-01
    相关资源
    最近更新 更多