Default and Parameterized constructors and object declaration

368 Views Asked by At

I've written this code:

#include<iostream>

using namespace std;

class Student {
   public:
      string name;
      int age;
      Student() {
         cout<<"Default constructor"<<endl;
      }
      Student(string name, int age) {
         this->name=name;
         this->age=age;
         cout<<"Parameterized constructor"<<endl;
      }
};

int main() {
   system("clear");
   Student s1={"abc", 20};                                                                                                                                                                                                                                                 return 0;                                                                                                                        }

Result:

Parameterized constructor

Conclusion: Defining object s1 like this Student s1={"abc", 20} calls parameterized constructor of class

Testing out conclusion:

#include<iostream>

using namespace std;

class Student {
   public:
      string name;
      int age;
};

int main() {
   system("clear");
   Student s1={"abc", 20};

   return 0;
}

But compiling the code above doesn't give any errors.

Questions:

  1. Why there is no errors even if we don't define any parameterized constructor inside class ?
  2. When we define class data members as private, we get some error:
5.cpp:12:12: error: no matching constructor for initialization of 'Student'
   Student s1={"abc", 20};
           ^  ~~~~~~~~~~~
5.cpp:5:7: note: candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 2 were provided
class Student {
      ^
5.cpp:5:7: note: candidate constructor (the implicit move constructor) not viable: requires 1 argument, but 2 were provided
5.cpp:5:7: note: candidate constructor (the implicit default constructor) not viable: requires 0 arguments, but 2 were provided
1 error generated.

Why we are getting this error now and not when data members were public ? :)

1

There are 1 best solutions below

0
On BEST ANSWER

For the 1st case, Student has user-declared constructors, Student s1={"abc", 20}; performs list-initialization, as the effect, the appropriate constructor Student::Student(string, int) is selected to construct s1.

If the previous stage does not produce a match, all constructors of T participate in overload resolution against the set of arguments that consists of the elements of the braced-init-list, ...

For the 2nd case, Student has no user-declared constructors, it's an aggregate and Student s1={"abc", 20}; performs aggregate-initialization, as the effect the data member name and age are initialized from "abc" and 20 directly.

An aggregate is one of the following types:

  • ...
  • ... class type (typically, struct or union), that has
  • ...
    • no user-declared or inherited constructors
  • ...

Each direct public base, (since C++17) array element, or non-static class member, in order of array subscript/appearance in the class definition, is copy-initialized from the corresponding clause of the initializer list.

If you make data members private, Student is not aggregate again. Student s1={"abc", 20}; still performs list-initialization and causes the error since no appropriate constructor exists.

An aggregate is one of the following types:

  • ...
  • ... class type (typically, struct or union), that has
    • no private or protected direct (since C++17)non-static data members
  • ...