假设我有一个C_student
类,它有几个成员,没有构造函数:
#include <iostream>
#include <string>
#include <initializer_list>
#include <typeinfo>
class c_student{
// private:
public:
std::string name = "John";
int mark = 5;
std::string second_name="Doe";
void print(){
std::cout << name <<" " << second_name << " : "<< mark<<"\n";
}
};
int main(){
c_student stud_c = {"Luke ",420};
stud_c.print();
c_student stud_d = {"Mark "};
stud_d.print();
}
这段代码工作正常,但假设我想在类中定义自定义构造函数:
c_student (std::string n):name(n){};
c_student() = default;
如果我将它们添加到类中,编译器会抱怨:
47_object_initialization.cpp:32:34: error: could not convert ‘{"Luke ", 420}’ from ‘<brace-enclosed initializer list>’ to ‘c_student’
32 | c_student stud_c = {"Luke ",420};
| ^
| |
| <brace-enclosed initializer list>
我想继续使用{}的默认构造函数,因此需要编写如下内容:
c_student( std::initializer_list <???>) = default; << Pseudo-code only!
但不知道具体是怎么回事。谁能在CPP参考的右页指出我的注意?
不幸的是,这是不可能的。代码最初工作的原因是聚合初始化。一旦您创建了用户定义的构造函数,您的类就不再是聚合类型
聚合是下列类型之一:
您可以使用大括号初始化,通过用以下构造函数替换所有构造函数来实现您想要的目标:
c_student (std::string name = "John", int mark = 5, std::string second_name = "Doe")
: name(name), mark(mark), second_name(second_name) {};
此外,您还可以删除默认的成员初始值设定项,因为构造C_student
的唯一方法是在未提供默认值的情况下为它们提供默认值。
这是一个演示。
您可以添加另一个用户定义的构造函数来处理具有两个条目的初始值设定项列表(并为每个可能的列表大小和顺序不断添加这样的构造函数)。以下编译并按预期工作:
#include <iostream>
#include <string>
class c_student {
private:
std::string name = "John";
int mark = 5;
std::string second_name = "Doe";
public:
void print() {
std::cout << name << " " << second_name << " : " << mark << "\n";
}
c_student(std::string n) : name(n) { } // Called for initializer list {"xxx"}
c_student(std::string n, int m) : name(n), mark(m) { } // Called for list {"xxx", m}
c_student(std::string n, std::string s, int m) : name(n), mark(m), second_name(s) { } // Called for list {"xxx", "yyy", m}
c_student() = default;
};
int main()
{
c_student stud_c = { "Luke", 420 };
stud_c.print();
c_student stud_d = { "Mark" };
stud_d.print();
c_student stud_e = { "John", "Smith", 333 };
stud_e.print();
return 0;
}