首页 > 解决方案 > 如何将一个类作为参数传递给另一个类的构造函数?

问题描述

我得到的问题是在 Person.cpp 内部,在构造函数中。当我这样做时,一切正常

Person::Person(string n,Birthday b)
:    name(n) ,
    birthday(b)
{}

当我这样做时,我得到错误......

Person::Person(string n,Birthday b) {
    name = n;
    birthday = b;
}

我的问题是如何将一个类作为参数传递给另一个类构造函数?

主要的:

#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;
}

人.cpp:

#include "Person.h"
#include <iostream>

using namespace std;

Person::Person(string n,Birthday b)
:    name(n) ,
    birthday(b)
{}

void Person::printInfo() {
    cout << name << " was born on ";
    birthday.printDate();
}

生日.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;
}

人.h:

#ifndef PERSON_H
#define PERSON_H

#include <string>
#include "Birthday.h"

using namespace std;

class Person {
public:
    Person(string n,Birthday b);
    void printInfo();
private:
    string name;
    Birthday birthday;
};

#endif // PERSON_H

生日.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

标签: c++

解决方案


问题

当您进入构造函数的主体时,必须已经构造了所有成员对象。

Person::Person(string n,Birthday b) 
{ // birthday must be constructed before here
    name = n;
    birthday = b; // this is an assignment, not an initialization
}

成员初始化器列表中没有初始化成员的情况下,正如问题中所做的那样

Person::Person(string n,Birthday b)
:    name(n) ,
    birthday(b)
{}

使用Birthday自动生成的复制构造函数,将使用默认构造函数。Birthday没有默认构造函数(如果您有用户定义的构造函数,编译器将不会创建默认构造函数),因此编译器会发出错误并且不会生成可用的对象。

选项(除了,比如,愤怒戒烟或其他东西)

1) 传入 aBirthday并如上复制。

旁注:您可以避免多余的Birthday物体挂在周围。如果构建到最近的 C++ 标准,您可以

Person bill("Billy Par", {13,4,1996});

如果你至少没有 C++11 支持,你可以

Person bill("Billy Par",Birthday(13,4,1996));

Birthday这会创建一个活到生产线末端的临时工。一个好的编译器知道优化 smurf 的技巧,所以你可能根本不知道临时变量的存在。

通过const引用传递

Person::Person(string n,const Birthday &b)
:    name(n) ,
    birthday(b)
{}

通过消除副本有可能会稍微好一些,但是现代编译器也知道这个技巧。

2) 向 的构造函数添加附加参数,Person并使用它们在成员初始化器列表中调用生日的构造函数。

Person::Person(string n, int d, int m, int y)
:    name(n) ,
    birthday(d,m,y)
{}

个人意见,我觉得

Person bill("Billy Par",Birthday(13,4,1996));

更好地表达意图和更灵活。

3)添加一个默认构造函数Birthday

我真的不喜欢这个选项。对于像这样的简单类,Birthday它还不错,但与选项一相比没有任何优势,并且使编译器更难应用一些有用的优化。对于复杂或难以构造的类,此选项会完成默认构造的工作,然后添加分配所需的任何工作。

旁注:如果 Modern C++ 可用,那么一个简单的默认构造函数很容易。添加

Birthday() = default;

到类定义。


推荐阅读