C++封装 之 成员对象

成员对象

一个类的数据成员是另一个类的对象,就叫做成员对象。

思考

  • 1:成员对象初始化和销毁时的调用顺序?
  • 2:如何用带有参数的构造函数初始化成员对象?

重要结论:

  • 实例化对象A时,如果对象A有对象成员B,那么先执行B的构造函数,再事项A的构造函数
  • 如果对象A有对象成员B,那么销毁对象A时,先执行A的析构函数,再执行B的析构函数。
  • 如果对象A有对象成员B,对象B没有默认构造函数,那么对象A必须在初始化列表中初始化对象B.

实例:


  对象成员
  要求:
       定义两个类:
       坐标类:Coordinate
           数据成员:横坐标m_iX、纵坐标m_iY
           成员函数:构造函数、析构函数、数据封装函数
       线段类:Line
           数据成员:点m_CoorA、点m_CoorB
           成员函数:构造函数、析构函数、数据封装函数、信息打印函数


1. 使用默认构造函数

test1.cpp源码

#include<iostream>
using namespace std;

/***************** 定义 Coordinate 类 *****************/
class Coordinate{
public:
    Coordinate();   //默认构造函数
    ~Coordinate(); 
    void setX(int x);
    void setY(int y);
    int getX();
    int getY();
private:
    int m_iX;
    int m_iY;
};

/***************** 定义 Line 类 *****************/
class Line{
public:
    Line();   //默认构造函数
    ~Line();
    void setA(int x, int y);
    void setB(int x, int y);
    void printInfo();
private:
    Coordinate m_CoorA;    // 对象成员
    Coordinate m_CoorB;    // 对象成员
};

/********************** Coordinate类的函数 ***************************/
Coordinate::Coordinate(){  //构造函数
    cout << "Coordinate()" <<endl;
}   
Coordinate::~Coordinate(){  //析构函数
    cout << "~Coordinate():(" <<m_iX <<" , "<< m_iY << ")"<<endl;
}
void Coordinate::setX(int x){
    m_iX = x;
}
void Coordinate::setY(int y){
    m_iY = y;
}
int Coordinate::getX(){
    return m_iX;
}
int Coordinate::getY(){
    return m_iY;
}

/********************** Line类的函数 ***************************/
Line::Line(){  //构造函数
    cout << "Line()"<<endl;
}
Line::~Line(){  //构造函数
    cout << "~Line()"<<endl;
}

void Line::setA(int x, int y){
    m_CoorA.setX(x);
    m_CoorA.setY(y);
}
void Line::setB(int x, int y){
    m_CoorB.setX(x);
    m_CoorB.setY(y);
}
void Line::printInfo(){   //打印两个点的坐标
    cout << "A = ("<< m_CoorA.getX() << "," << m_CoorA.getY() << ")" << endl;
    cout << "B = ("<< m_CoorB.getX() << "," << m_CoorB.getY() << ")" << endl;
}

/************************** 测试主函数 *******************************/
int main(){
    
    Line *p = new Line();  // 声明Line类型的指针 

    p->setA(1,2);      //调用Coordinate类的数据封装函数来实例化点
    p->setB(3,4);
    p->printInfo();    //打印

    delete p;         // 销毁Line对象 
    p = NULL;         //置空指针
    system("pause");
    return 0;
}

运行结果:

Coordinate()
Coordinate()
Line()
A = (1,2)
B = (3,4)
~Line()
~Coordinate():(3 , 4)
~Coordinate():(1 , 2)

说明:

  1. 调用顺序:

    • 初始化时,先实例化Coordinate对象,再实例化Line对象
    • 销毁时,先销毁Line对象,后销毁Coordinate对象
  2. 由于使用的时默认构造函数,所以实例化了Line对象之后,还需要调用Coordinate类的数据封装函数来实例化点。

2. 使用有参数的构造函数

  • 前面的例子中使用了默认构造函数(没有参数),实例化Line对象之后,还需要调用Coordinate的数据封装函数来初始化两个点
  • 事实上,当实例化一个Line对象时,我们希望同时初始化了两个点,这就需要使用带有参数的构造函数
  • 使用初始化列表列表给有参数的构造函数传参

test2.cpp源码

#include<iostream>
using namespace std;
/***************** 定义 Coordinate 类 *****************/
class Coordinate{
public:
    Coordinate(int x, int y);   //有参数的构造函数
    ~Coordinate(); 
    void setX(int x);
    void setY(int y);
    int getX();
    int getY();
private:
    int m_iX;
    int m_iY;
};

/***************** 定义 Line 类 *****************/
class Line{
public:
    Line(int x1, int y1, int x2, int y2);   //有参数的构造函数
    ~Line();
    void setA(int x, int y);
    void setB(int x, int y);
    void printInfo();
private:
    Coordinate m_CoorA;    // 对象成员
    Coordinate m_CoorB;    // 对象成员
};

/********************** Coordinate类的函数 ***************************/
Coordinate::Coordinate(int x, int y){  //有参数的构造函数的实现
    m_iX = x;
    m_iY = y;
    cout << "Coordinate():(" <<m_iX <<" , "<< m_iY << ")"<<endl;
}   
Coordinate::~Coordinate(){  //析构函数
    cout << "~Coordinate():(" <<m_iX <<" , "<< m_iY << ")"<<endl;
}
void Coordinate::setX(int x){
    m_iX = x;
}
void Coordinate::setY(int y){
    m_iY = y;
} 
int Coordinate::getX(){
    return m_iX;
}
int Coordinate::getY(){
    return m_iY;
}

/********************** Line类的函数 ***************************/
Line::Line(int x1, int y1, int x2, int y2):m_CoorA(x1, y1),m_CoorB(x2, y2){  //用初始化列表给有参数的构造函数传参
    cout << "Line()"<<endl;
}
Line::~Line(){  //构造函数
    cout << "~Line()"<<endl;
}

void Line::setA(int x, int y){
    m_CoorA.setX(x);
    m_CoorA.setY(y);
}
void Line::setB(int x, int y){
    m_CoorB.setX(x);
    m_CoorB.setY(y);
}
void Line::printInfo(){  //打印两个点的坐标
    cout << "A = ("<< m_CoorA.getX() << "," << m_CoorA.getY() << ")" << endl;
    cout << "B = ("<< m_CoorB.getX() << "," << m_CoorB.getY() << ")" << endl;
}

/************************** 测试主函数 *******************************/
int main(){
    
    Line *p = new Line(1,2,3,4);   // 实例化对象时,直接传参数 

    p->printInfo();         //打印

    delete p;               // 销毁Line对象 */
    p = NULL;               //置空指针
    system("pause");
    return 0;
}

运行结果:

Coordinate():(1 , 2)
Coordinate():(3 , 4)
Line()
A = (1,2)
B = (3,4)
~Line()
~Coordinate():(3 , 4)
~Coordinate():(1 , 2)

说明:

  • 将默认构造函数改造成带参数的构造函数之后,使用初始化列表进行传参
  • 实例化Line对象之后,自动初始化了两个点
posted @ 2021-08-25 12:05  赶紧学习  阅读(233)  评论(0编辑  收藏  举报