为何出现‘no matching function for call to Date::Date()’编译错误?
错误原因
编译错误的核心是:Date类没有定义无参默认构造函数,你新增的Todo_item(const string& s)构造函数中,没有在初始化列表里显式初始化Todo_item的Date类型成员。编译器会自动尝试调用Date的默认构造函数来初始化该成员,但Date只有带参构造函数,因此触发报错。
解决方法
在Todo_item(const string& s)的初始化列表中,先从输入字符串(如"25/12/2018! Buy gifts")里解析出日期部分,拆分出日、月、年的数值,用这些数值构造Date对象,显式初始化Todo_item的Date成员即可。
示例代码
Date类实现
#include <string> #include <stdexcept> #include <algorithm> #include <iostream> class Date { private: int day; int month; int year; // 校验日期合法性的辅助函数 bool is_valid(int d, int m, int y) { if (m < 1 || m > 12) return false; if (d < 1) return false; // 各月份天数,二月处理闰年 int days_in_month[] = {31,28,31,30,31,30,31,31,30,31,30,31}; if (m == 2 && ((y % 4 == 0 && y % 100 != 0) || (y % 400 == 0))) { days_in_month[1] = 29; } return d <= days_in_month[m-1]; } public: // 带参构造函数,初始化列表+合法性校验 Date(int d, int m, int y) : day(d), month(m), year(y) { if (!is_valid(d, m, y)) { throw std::invalid_argument("无效日期"); } } // 提供getter方法供外部访问日期字段 int get_day() const { return day; } int get_month() const { return month; } int get_year() const { return year; } };
Todo_item类实现
class Todo_item { private: std::string description; Date deadline; bool is_completed; // 静态辅助函数:从输入字符串中解析出Date对象 static Date parse_date(const std::string& s) { size_t delimiter_pos = s.find('!'); if (delimiter_pos == std::string::npos) { throw std::invalid_argument("字符串格式错误,缺少'!'分隔符"); } // 提取日期部分并去除前后空格 std::string date_str = s.substr(0, delimiter_pos); date_str.erase(date_str.begin(), std::find_if(date_str.begin(), date_str.end(), [](int ch) { return !std::isspace(ch); })); date_str.erase(std::find_if(date_str.rbegin(), date_str.rend(), [](int ch) { return !std::isspace(ch); }).base(), date_str.end()); // 拆分日、月、年 size_t slash1 = date_str.find('/'); size_t slash2 = date_str.find('/', slash1 + 1); if (slash1 == std::string::npos || slash2 == std::string::npos) { throw std::invalid_argument("日期格式错误,应为dd/mm/yyyy"); } int day = std::stoi(date_str.substr(0, slash1)); int month = std::stoi(date_str.substr(slash1 + 1, slash2 - slash1 - 1)); int year = std::stoi(date_str.substr(slash2 + 1)); return Date(day, month, year); } // 静态辅助函数:从输入字符串中解析出任务描述 static std::string parse_desc(const std::string& s) { size_t delimiter_pos = s.find('!'); if (delimiter_pos == std::string::npos) { throw std::invalid_argument("字符串格式错误,缺少'!'分隔符"); } // 提取描述部分并去除前后空格 std::string desc = s.substr(delimiter_pos + 1); desc.erase(desc.begin(), std::find_if(desc.begin(), desc.end(), [](int ch) { return !std::isspace(ch); })); desc.erase(std::find_if(desc.rbegin(), desc.rend(), [](int ch) { return !std::isspace(ch); }).base(), desc.end()); return desc; } public: // 原构造函数:接收描述和日期 Todo_item(const std::string& desc, const Date& date) : description(desc), deadline(date), is_completed(false) {} // 新增构造函数:解析字符串生成Todo_item Todo_item(const std::string& s) : description(parse_desc(s)), deadline(parse_date(s)), is_completed(false) {} // 打印任务信息的辅助方法 void print() const { std::cout << (is_completed ? "[已完成] " : "[未完成] ") << description << " | 截止日期:" << deadline.get_day() << "/" << deadline.get_month() << "/" << deadline.get_year() << std::endl; } };
测试代码
int main() { try { Todo_item todo("25/12/2018! Buy gifts"); todo.print(); } catch (const std::exception& e) { std::cerr << "错误:" << e.what() << std::endl; } return 0; }
关键说明
- 必须显式初始化Date成员:因为
Date没有默认构造函数,编译器无法自动初始化该成员,必须在Todo_item构造函数的初始化列表中,用Date的带参构造函数显式构造。 - 拆分字符串的逻辑封装:把日期和描述的解析逻辑封装为静态辅助函数,既可以在初始化列表中调用,也能提升代码的可读性和复用性。
- 处理空格问题:解析时去除日期和描述前后的空格,避免因格式不规整导致的解析错误。
内容的提问来源于stack exchange,提问作者user21082127
相关产品推荐
相关产品推荐

