You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将类作为参数传入另一个类的构造函数?附赋值写法报错问题

问题分析与解决方案

嘿,这个问题其实是C++类成员初始化机制的典型坑点,我来给你拆解清楚:

为什么直接赋值写法会报错?

当你在Person的构造函数体内写birthday = b;的时候,C++的执行顺序是这样的:

  1. 先初始化Person的所有成员变量:对于birthday这个Birthday类型的成员,编译器会尝试调用它的默认构造函数(也就是不带参数的Birthday())来创建对象。
  2. 然后才会执行构造函数体内的赋值语句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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 04:10:17