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

Is there any way by which we can pass parameters to the constructor?

Error: no default constructor exists for class "Student"
2
  • 1
    Why do you want to use new instead of std::vector? For the latter the problem of creating objects with parameters is somewhat simpler - you can write a loop instead of very long initializer list. Commented Apr 7, 2021 at 13:01
  • In cases like this, aside from emplace_back, new or that C++11 initialization method, there's always the option of the good old init-Function. Remove the parameters from the constructor (or supply them with default values), but also define an initfunction, which does the same thing. Then you can initialize the objects after having allocated the object. Even in a loop if you want. Commented Apr 7, 2021 at 13:24

3 Answers 3

1

From cppreference:

::(optional) new (placement_params)(optional) ( type ) initializer(optional)

If initializer is a brace-enclosed list of arguments, the array is aggregate-initialized. (since C++11)

You can use optional aggregate initializer like this:

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

however it is not very comfortable if you have many students (like 30 in your example).

Sign up to request clarification or add additional context in comments.

1 Comment

Well, I would just go for std::vector<Student> vec; (followed by reserve to avoid memory reallocs) and then in the loop vec.push_back(Student(i, "whatever"));. But you asked about operator new, so I leave this example just for reference.
1

I would use a std::vector if I were you. However, if you prefer to stick to array, here is how I would have done it with array (and below it the std::vector example)

#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();
    }
}

2 Comments

Using a vector of pointers is unnecessary, you can just use a vector of Student objects
Done !! Thanks for you review again :)
0

A straightforward way to do as you ask is to use 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));

However, you may consider just adding a default constructor. It would be up to you to know whether the object was initialized or not (I strongly recommend not adding a member like bool is_initialized, in case you might be tempted to)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.