我写了这段代码:
#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的调用类的参数化构造函数
检验结论:
#include<iostream>
using namespace std;
class Student {
public:
string name;
int age;
};
int main() {
system("clear");
Student s1={"abc", 20};
return 0;
}
但是,编译上面的代码不会产生任何错误。
问题:
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.
为什么我们现在要得到这个错误,而不是当数据成员是公开的?:)
发布于 2022-02-07 04:44:15
对于第一种情况,Student
有用户声明的构造函数,Student s1={"abc", 20};
执行列表初始化,作为效果,选择合适的构造函数Student::Student(string, int)
来构造s1
。
如果上一阶段不产生匹配,则T的所有构造函数都参与对包含大括号元素的参数集的重载解析,.
对于第二种情况,Student
没有用户声明的构造函数,它是一个聚合,Student s1={"abc", 20};
执行聚合-初始化,因为数据成员name
和age
直接从"abc"
和20
初始化。
聚合是下列类型之一:
每个
direct public base, (since C++17)
数组元素,或非静态类成员,按照类定义中数组下标/外观的顺序,从初始化程序列表的对应子句复制初始化。
如果将数据成员设为private
,则Student
不再聚合。由于不存在适当的构造函数,Student s1={"abc", 20};
仍然执行列表初始化并导致错误。
聚合是下列类型之一:
direct (since C++17)
非静态数据成员。https://stackoverflow.com/questions/71013555
复制相似问题