c++类与对象(一)

c++类与对象—组合的实例

设计一个用于人事管理的 People(人员)类。考虑到通用性,这里只抽象出所有类型人员都具有的属性:number(编号)、gender(性别)、birthday(出生日期)、id(身份证号)等。其中“出生日期”声明为一个“日期”类的内嵌子对象。用成员函数实现对人员信息的录入和显示。要求包括:构造函数和析构函数、复制构造函数、内联成员函数、组合。


类的组合描述的就是一个类内嵌其他类的对象作为成员的情况,他们之间的关系是一种包含与被包含的关系。对于稍微复杂的问题都可以使用组合来描述,这比较符合逐步求精的思维规律。

当创建类的对象时,如果这个类具有内嵌对象成员,那么各个内嵌对象将首先被自动创建。因为部件对象是复杂对象的一部分,因此,在创建对象时既要对本类的基本类型数据成员进行初始化,又要对内嵌对象成员进行初始化。这时,理解这些对象的构造函数被调用的顺序就很重要。

组合类构造函数定义的一般形式为:

类名 :: 类名(形参表) : 内嵌对象1(形参表) , 内嵌对象2(形参表),……

其中内嵌对象1(形参表) , 内嵌对象2(形参表),……称作初始化列表,其作用是对内嵌对象进行初始化

例如:定义一个Data类

//Data类实现
class Data{
public:
    Data(int newY,int newM,int newD);   // 构造函数
    Data();                             // 构造函数重载
    Data(Data &d);                      // 复制构造函数
    ~Data(){}                          // 析构函数
    void showData();
private:
    int year;
    int month;
    int day;
};

再定义一个People类

// People类实现
class People{
public:
    People(int number1,char sex1,Data birthday1,string id1);    // 构造函数
    People(People &p);                                          // 构造函数重载
    ~People(){}                                                    // 析构函数
    void showInfo();
private:
    int number;
    char sex;
    Data birthday;      // birthday为内嵌Data对象
    string id;
};

其中People(int number1,char sex1,Data birthday1,string id1);为声明显式构造函数,birthday1为People类中的形参,再来看看该函数的实现:

// 组合类People构造函数
People::People(int number1,char sex1,Data birthday1,string id1):birthday(birthday1){    // birthday 为内嵌Data对象
    number = number1;
    sex = sex1;
    id = id1;
}

People类中包含内嵌Data对象birthday1,:后为内嵌对象的初始化列表

在创建一个组合类对象时,不仅它自身的构造函数的函数体将被执行,而且还将调用其内嵌对象的构造函数。这时构造函数的调用顺序如下:

  1. 调用内嵌对象的构造函数,调用顺序按照内嵌对象在组合类的定义中出现的次序。注意:内嵌对象在构造函数的初始化列表中出现的顺序与内嵌对象构造函数的调用顺序无关
  2. 执行本类构造函数的函数体

对于析构函数来讲,析构函数的调用执行顺序与构造函数刚好相反。析构函数的函数体被执行完毕后,内嵌对象的析构函数被一一执行,这些内嵌对象的析构函数调用顺序与它们在组合类的定义中出现的次序刚好相反。


复制构造函数

如果要为组合编写复制构造函数,则需要为内嵌成员对象的复制构造函数传递参数。例如,假设A类中包含B类的对象b作为成员,A类的复制构造函数形式如下:

A :: A(A &a) : b(a.b) {……}  //调用b的复制构造函数

Data类的复制构造函数

// Data类复制构造函数
Data::Data(Data &d){
year = d.year;
month = d.month;
day = d.day;
}

People类的复制构造函数:

// People复制构造函数
People::People(People &p):birthday(p.birthday){
    number = p.number;
    sex = p.sex;
    id = p.id;
}

People类复制构造函数中,:后birthday(p.birthday)调用了b的复制构造函数


本问题的具体实现代码如下:

#include "iostream"
#include "string"
#include "cstring"
using namespace std;

class Data{
public:
    Data(int newY,int newM,int newD);   // 构造函数
    Data();                             // 构造函数重载
    Data(Data &d);                      // 复制构造函数
    ~Data(){}                          // 析构函数
    void showData();
private:
    int year;
    int month;
    int day;
};

//Data类实现
Data::Data(int newY,int newM,int newD){
    year = newY;
    month = newM;
    day = newD;
}

Data::Data(){
    year = 2018;
    month = 1;
    day = 1;
}

// Data类复制构造函数
Data::Data(Data &d){
    year = d.year;
    month = d.month;
    day = d.day;
}

void Data::showData(){
    cout << "birthday: " << year << " " << month << " " << day << endl;
}


// People类实现
class People{
public:
    People(int number1,char sex1,Data birthday1,string id1);    // 构造函数
    People(People &p);                                          // 构造函数重载
    ~People(){}                                                    // 析构函数
    void showInfo();
private:
    int number;
    char sex;
    Data birthday;      // birthday为内嵌Data对象
    string id;
};

// 组合类People构造函数
People::People(int number1,char sex1,Data birthday1,string id1):birthday(birthday1){    // birthday 为内嵌Data对象
    number = number1;
    sex = sex1;
    id = id1;
}

// People复制构造函数
People::People(People &p):birthday(p.birthday){
    number = p.number;
    sex = p.sex;
    id = p.id;
}

inline void People::showInfo(){
    cout << "number: " << number << endl;
    cout << "sex: " << sex << endl;
    birthday.showData();
    cout << "id: " << id << endl;
}

int main(){
    Data birthday(1997,3,19);
    People x(1,'F',birthday,"123");
    x.showInfo();
}

你可能感兴趣的:(学习笔记)