如何将类作为参数传入另一个类的构造函数?附赋值写法报错问题
问题分析与解决方案
嘿,这个问题其实是C++类成员初始化机制的典型坑点,我来给你拆解清楚:
为什么直接赋值写法会报错?
当你在Person的构造函数体内写birthday = b;的时候,C++的执行顺序是这样的:
- 先初始化
Person的所有成员变量:对于birthday这个Birthday类型的成员,编译器会尝试调用它的默认构造函数(也就是不带参数的Birthday())来创建对象。 - 然后才会执行构造函数体内的赋值语句
birthday = b;。
但你的Birthday类只定义了一个带三个int参数的构造函数,根据C++规则,当你自定义了构造函数后,编译器就不会自动生成默认构造函数了。所以第一步初始化birthday的时候,找不到可用的默认构造函数,自然就报错了。
而初始化列表Person::Person(string n,Birthday b) : name(n) , birthday(b) {}的逻辑是直接用传入的b对象,通过拷贝构造函数(编译器会自动生成这个)来初始化birthday成员,跳过了默认构造的步骤,所以能正常运行。
解决办法
方法1:给Birthday添加默认构造函数
这是最直接的方式,让编译器能完成成员的默认初始化,之后再执行赋值:
修改Birthday.h:
#ifndef BIRTHDAY_H #define BIRTHDAY_H class Birthday { public: Birthday(); // 添加默认构造函数声明 Birthday(int d,int m,int y); void printDate(); private: int day; int month; int year; }; #endif // BIRTHDAY_H
修改Birthday.cpp:
#include "Birthday.h" #include <iostream> using namespace std; // 实现默认构造函数,可以给成员赋默认值 Birthday::Birthday() : day(0), month(0), year(0) {} Birthday::Birthday(int d,int m,int y) { day = d; month = m; year = y; } void Birthday::printDate() { cout << day << "/" << month << "/" << year << endl; }
这样你用直接赋值的构造函数写法就不会报错了。
方法2:坚持使用初始化列表(更推荐)
初始化列表是C++中初始化类成员的最优方式,它能避免不必要的对象构造和赋值操作,效率更高,而且能初始化那些没有默认构造函数的成员(比如你的场景)。你的原始代码里的初始化列表写法本身就是正确的,完全可以继续用它。
另外,还可以优化一下构造函数的参数,把Birthday b改成const Birthday& b,避免不必要的对象拷贝:
Person::Person(string n, const Birthday& b) : name(n), birthday(b) {}
对应的Person.h里的构造函数声明也要改成:
Person(string n, const Birthday& b);
方法3:给Birthday添加赋值运算符重载(可选)
不过这个其实没必要,因为编译器会自动生成默认的赋值运算符,只要有默认构造函数,方法1已经覆盖了这个场景。
完整可运行代码(以方法2优化版为例)
main.cpp
#include <iostream> #include "Birthday.h" #include "Person.h" using namespace std; int main() { Birthday birth(13,4,1996); Person bill("Billy Par",birth); bill.printInfo(); return 0; }
Person.cpp
#include "Person.h" #include <iostream> using namespace std; Person::Person(string n, const Birthday& b) : name(n), birthday(b) {} void Person::printInfo() { cout << name << " was born on "; birthday.printDate(); }
Person.h
#ifndef PERSON_H #define PERSON_H #include <string> #include "Birthday.h" using namespace std; class Person { public: Person(string n, const Birthday& b); void printInfo(); private: string name; Birthday birthday; }; #endif // PERSON_H
Birthday.cpp
#include "Birthday.h" #include <iostream> using namespace std; Birthday::Birthday(int d,int m,int y) { day = d; month = m; year = y; } void Birthday::printDate() { cout << day << "/" << month << "/" << year << endl; }
Birthday.h
#ifndef BIRTHDAY_H #define BIRTHDAY_H class Birthday { public: Birthday(int d,int m,int y); void printDate(); private: int day; int month; int year; }; #endif // BIRTHDAY_H
内容的提问来源于stack exchange,提问作者jas0355
相关产品推荐
相关产品推荐

