2025年4月10日 星期四 乙巳(蛇)年 正月十一 设为首页 加入收藏
rss
您当前的位置:首页 > 计算机 > 编程开发 > VC/VC++

C++子类对象―子类对象的构造和析构

时间:01-10来源:作者:点击数:82

对象在使用之前,始终是要经历“构造”这个过程的。在第15章,我们了解到当一个对象的成员数据是另一个对象的时候,就先运行成员对象的构造函数,再运行父对象的构造函数。但是继承的出现,会引入子类的构造函数。这时候,这些构造函数的运行顺序又是怎样的呢?

子类对象的构造

讨论子类对象的构造,就是在讨论子类对象的生成方式。它是先生成父类对象的成员,再对其进行扩展呢,还是先生成子类对象的成员,然后再对其进行补充?我们还是修改一下程序17.3.2,用事实来解决这个问题:(程序17.4.1)

//node.h和linklist.h同程序17.3.2
//stack.h

  • #include "linklist.h"
  • class Stack:private Linklist//私有继承链表类
  • {
  • public:
  • bool push(int i,char c);
  • bool pop(int &i,char &c);
  • void show();
  • Stack(int i,char c);
  • Stack();
  • };
  • Stack::Stack(int i,char c):Linklist(i,c)//将子类构造函数的参数传递给父类的构造函数
  • {
  • cout <<"Stack constructor with parameter is running..." <<endl;
  • }
  • Stack::Stack()//子类构造函数
  • {
  • cout <<"Stack constructor is running..." <<endl;
  • }
  • bool Stack::push(int i,char c)
  • {
  • while (pcurrent->next!=NULL)
  • pcurrent=pcurrent->next;
  • return Insert(i,c);
  • }
  • bool Stack::pop(int &i,char &c)
  • {
  • while (pcurrent->next!=NULL)
  • pcurrent=pcurrent->next;
  • i=pcurrent->idata;
  • c=pcurrent->cdata;
  • return Delete();
  • }
  • void Stack::show()
  • {
  • Show();
  • }

//main.cpp

  • #include <iostream>
  • #include "stack.h"
  • int main()
  • {
  • Stack ss(1,'4');//调用带参数的构造函数
  • cout <<"Stack ss constructed" <<endl;
  • ss.show();
  • Stack zz; //调用不带参数的构造函数
  • cout <<"Stack zz constructed" <<endl;
  • zz.show();
  • return 0;
  • }

运行结果:
Node constructor is running...
Linklist constructor is running...
Stack constructor with parameter is running...
Stack ss constructed
1 4
Node constructor is running...
Linklist constructor is running...
Stack constructor is running...
Stack zz constructed
0 0
Linklist destructor is running...
Node destructor is running...
Linklist destructor is running...
Node destructor is running...

这个程序中有三个类,其中Stack类是Linklist类的子类,Node类的对象是Linklist类的成员数据。根据程序的运行结果,我们可以确定,父类的成员对象仍然是最先构造的,接着是运行父类的构造函数,最后运行子类的构造函数。也就是说子类对象是在父类对象的基础上扩展而成的。

另外,如果我们希望把子类的构造函数的参数传递给父类的构造函数时,可以在子类的构造函数定义中用以下格式调用父类的构造函数:
    子类名::构造函数名(参数表):父类名(参数表)

如程序17.4.1就是用上述方法实现子类和父类的构造函数参数传递。这样的方法不仅使子类对象的初始化变得简单,并且使子类和父类的构造函数分工明确,易于维护。

子类对象的析构

在第15章中介绍析构函数的时候,我们就说它的运行顺序往往是和构造函数的运行顺序相反的。那么使用了继承之后,是否依然是这样的规律呢?我们继续修改程序17.4.1,尝试验证我们的猜想。 

//node.h和linklist.h同程序17.3.2
//stack.h

  • #include "linklist.h"
  • class Stack:private Linklist
  • {
  • public:
  • bool push(int i,char c);
  • bool pop(int &i,char &c);
  • void show();
  • Stack(int i,char c);
  • Stack();
  • ~Stack();//析构函数
  • };
  • Stack::Stack(int i,char c):Linklist(i,c)
  • {
  • cout <<"Stack constructor with parameter is running..." <<endl;
  • }
  • Stack::Stack()
  • {
  • cout <<"Stack constructor is running..." <<endl;
  • }
  • Stack::~Stack()
  • {
  • cout <<"Stack destructor is running..." <<endl;
  • }
  • bool Stack::push(int i,char c)
  • {
  • while (pcurrent->next!=NULL)
  • pcurrent=pcurrent->next;
  • return Insert(i,c);
  • }
  • bool Stack::pop(int &i,char &c)
  • {
  • while (pcurrent->next!=NULL)
  • pcurrent=pcurrent->next;
  • i=pcurrent->idata;
  • c=pcurrent->cdata;
  • return Delete();
  • }
  • void Stack::show()
  • {
  • Show();
  • }

//main.cpp

  • #include <iostream>
  • #include "stack.h"
  • int main()
  • {
  • Stack zz;
  • cout <<"Stack zz constructed" <<endl;
  • zz.show();
  • return 0;
  • }

运行结果:
Node constructor is running...
Linklist constructor is running...
Stack constructor is running...
Stack zz constructed
0 0
Stack destructor is running...
Linklist destructor is running...
Node destructor is running...

根据运行结果,我们可以确认:使用了继承之后,析构函数的运行顺序依然恰好与构造函数的运行顺序相反。

方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门