如何在Book类构造函数中初始化私有Author对象数组?解决编译报错
这个报错的原因其实很清晰:
- 你的
author类只定义了带参数的构造函数,没有提供无参的默认构造函数; - 当你在
book类中声明author writer[3]这个数组时,编译器会自动尝试调用每个author对象的默认构造函数完成数组元素初始化,但因为找不到对应的默认构造函数,所以抛出了这个错误; - 另外,你在
book构造函数初始化列表里写的writer[3]{writer[3]}是完全错误的语法,C++里不能这样初始化数组。
下面给你三种不同的解决方案,你可以根据实际需求选择:
方案一:给author类添加默认构造函数
这是最简单的方案,适合允许author对象存在“空状态”的场景:
#include<iostream> #include<string> using namespace std; class author { string name; string email; public: // 添加无参默认构造函数,初始化空的名字和邮箱 author() : name(""), email("") {} // 原有的带参构造函数 author(string name, string email): name{name}, email{email} {} // 其他成员函数... }; class book { double price; string name; author writer[3]; public: // 修改后的构造函数:先默认初始化数组,再拷贝传入的作者数组元素 book(double price, string name, const author writers[3]) : price{price}, name{name} { // 逐个拷贝数组元素到类内的writer数组 for(int i = 0; i < 3; ++i) { writer[i] = writers[i]; } } // 其他成员函数... }; int main() { // 示例用法 author a1("Alice", "alice@example.com"); author a2("Bob", "bob@example.com"); author a3("Charlie", "charlie@example.com"); author authors[] = {a1, a2, a3}; book myBook(29.99, "C++ Primer", authors); return 0; }
方案二:在book构造函数中逐个初始化数组元素(不添加默认构造)
如果你的author类不应该存在空状态,那就不要添加默认构造函数,而是直接在book的构造函数初始化列表里逐个初始化数组的每个元素:
#include<iostream> #include<string> using namespace std; class author { string name; string email; public: author(string name, string email): name{name}, email{email} {} // 其他成员函数... }; class book { double price; string name; author writer[3]; public: // 直接传入三个author对象,在初始化列表中逐个初始化数组元素 book(double price, string name, const author& a1, const author& a2, const author& a3) : price{price}, name{name}, writer{a1, a2, a3} {} // 或者支持初始化列表参数(C++11及以上),更灵活 book(double price, string name, initializer_list<author> authors) : price{price}, name{name} { if(authors.size() != 3) { // 处理参数数量错误,比如抛出异常 throw invalid_argument("必须传入3个作者对象"); } // 把初始化列表的元素拷贝到数组 copy(authors.begin(), authors.end(), writer); } // 其他成员函数... }; int main() { // 示例用法1:直接传三个author对象 book myBook1(29.99, "C++ Primer", author("Alice", "alice@example.com"), author("Bob", "bob@example.com"), author("Charlie", "charlie@example.com") ); // 示例用法2:用初始化列表(C++11+) book myBook2(39.99, "Effective C++", { author("Scott Meyers", "scott@example.com"), author("Someone", "someone@example.com"), author("Another", "another@example.com") }); return 0; }
方案三:改用标准容器std::array或std::vector(推荐)
在现代C++中,尽量避免使用原生数组,改用std::array(固定大小)或std::vector(动态大小)会更灵活,初始化也更方便,而且不需要依赖默认构造函数:
#include<iostream> #include<string> #include<array> // 包含std::array的头文件 using namespace std; class author { string name; string email; public: author(string name, string email): name{name}, email{email} {} // 其他成员函数... }; class book { double price; string name; std::array<author, 3> writer; // 用std::array代替原生数组 public: // 直接传入std::array对象初始化 book(double price, string name, std::array<author, 3> authors) : price{price}, name{name}, writer{authors} {} // 或者支持传入三个author对象 book(double price, string name, const author& a1, const author& a2, const author& a3) : price{price}, name{name}, writer{{a1, a2, a3}} {} // 其他成员函数... }; int main() { std::array<author, 3> authors = { author("Alice", "alice@example.com"), author("Bob", "bob@example.com"), author("Charlie", "charlie@example.com") }; book myBook(29.99, "C++ Primer", authors); return 0; }
各方案优缺点总结
- 方案一:实现简单,但如果
author对象不应该有“空值”状态,会破坏类的封装性; - 方案二:严格保证每个
author对象都被正确初始化,但构造函数参数较多,灵活性稍差; - 方案三:符合现代C++编程风格,容器操作更便捷,类型更安全,推荐优先使用。
内容的提问来源于stack exchange,提问作者Abderrahmane Bensalem
相关产品推荐
相关产品推荐

