默认和参数化构造函数和对象声明

Default and Parameterized constructors and object declaration

我写过这段代码:

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

结果:

Parameterized constructor

结论:这样定义对象s1 Student s1={"abc", 20}调用了class

的参数化构造函数

测试得出结论:

#include<iostream>

using namespace std;

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

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

   return 0;
}

但是编译上面的代码没有给出任何错误。

问题:

  1. 为什么在class里面不定义参数化构造函数也没有报错?
  2. 当我们将 class 数据成员定义为 private 时,我们得到一些错误:
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.

为什么我们现在收到此错误,而不是在数据成员为 public 时收到此错误? :)

对于第一种情况,Student有user-declared个构造函数,Student s1={"abc", 20};执行list-initialization,作为效果,选择合适的构造函数Student::Student(string, int)构造 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, ...

对于第二种情况,Student 没有 user-declared 构造函数,它是一个聚合,Student s1={"abc", 20}; 执行 aggregate-initialization,作为数据成员 nameage直接从"abc"20初始化。

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.

如果您将数据成员设为 private,则 Student 不会再次聚合。 Student s1={"abc", 20}; 仍然执行 list-initialization 并导致错误,因为不存在合适的构造函数。

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
  • ...