C++委托构造函数与临时对象传参初始化报错如何修复?
错误修复方案
错误1:initial value of reference to non-const must be an lvalue
错误原因
add_movie方法的参数是非常量左值引用Movie &movie1,无法绑定你传入的临时匿名对象Movie{ "Dictator","PG-13",3 }(该对象属于右值,仅支持绑定到常量左值引用或者右值引用)。
修复方法
- 将
add_movie、check_movie的入参都改为const Movie &movie1,常量左值引用天然支持绑定右值,也符合两个方法不会修改入参的语义。 - 同步修正
check_movie的逻辑错误:原逻辑只会比对第一个元素就返回结果,无法正确校验整个列表的重复项;同时修正add_movie的判断逻辑,原逻辑写反了存在性判断条件。
错误2:constructor delegates directly or indirectly to itself
错误原因
你的Movie类设计存在冗余的Movie *data成员,且拷贝构造函数Movie(const Movie &source) :Movie{ *source.data }会调用自身,形成无限递归委托;同时三个参数的构造函数没有初始化data指针,后续操作data属于野指针访问,会直接触发运行时崩溃。
修复方法
- 删除冗余的
Movie *data成员,Movie本身已经包含所有需要的属性,不需要额外指针存储。 - 重写拷贝构造、移动构造、指针参数构造函数,直接委托到三参数基础构造函数,避免递归。
完整修复后代码
#include <iostream> #include <vector> #include <string> #include <utility> // 用于std::move优化移动语义 using namespace std; class Movie { private: friend class Movies; string name; string rating; int times_watched; public: // 基础构造函数 Movie(string name1,string rating1, int times_watched1) :name{move(name1)},rating{move(rating1)},times_watched{times_watched1} {} // 指针参数构造函数,委托到基础构造 Movie(const Movie *data1) :Movie(data1->name, data1->rating, data1->times_watched) {} // 拷贝构造函数,委托到基础构造,避免递归 Movie(const Movie &source) :Movie(source.name, source.rating, source.times_watched) {} // 移动构造函数 Movie(Movie &&source) noexcept :name(move(source.name)), rating(move(source.rating)), times_watched(source.times_watched) {} }; class Movies { private: vector <Movie> list; public: // 入参加const,方法本身加const符合只读语义 bool check_movie(const Movie &movie1) const { // 修正逻辑:遍历所有元素,找到重复返回false for (const auto& item : list) { if (item.name == movie1.name) { return false; } } // 遍历完没找到才返回true return true; } // 入参加const void add_movie(const Movie &movie1) { // 修正逻辑:不存在才添加 if (check_movie(movie1)) { list.push_back(movie1); } else { cout << "Movie is already in the list\n"; } } void increment_watched_count(const string &movie_name) { for (auto& item : list) { if (item.name == movie_name) { item.times_watched++; return; } } cout << "Movie is not on the list\n"; } void display_list() const { for (const auto& item : list) { cout << item.name << " | " << item.rating << " | " << item.times_watched << "\n"; } } }; int main() { Movies collection; collection.add_movie(Movie{ "Dictator","PG-13",3 }); collection.display_list(); return 0; }
内容的提问来源于stack exchange,提问作者Ioan Săsărman
相关产品推荐
相关产品推荐

