不是什么问题,我写的一个测试程序,大家看看,谈谈感受;顺便散点分。

fibbery 2009-03-17 10:12:04
#include <iostream>
#include <string>


class CBase
{
public:
CBase()
{
vfunc("CBase Constructor");
}
~CBase()
{
vfunc("CBase Destructor");
}
virtual void vfunc(std::string str)
{
std::cout<<"CBase::vfunc:"<<str<<std::endl;
}
};

class CDerived: public CBase
{
public:
CDerived()
{
vfunc("CDerived Constructor");
}
~CDerived()
{
vfunc("CDerived Destructor");
}
virtual void vfunc(std::string str)
{
std::cout<<"CDerived::vfunc:"<<str<<std::endl;
}
};

int main(int argc, char * argv[])
{
CDerived d1;
return 0;
}

E:\MyDocs\debug>test
CBase::vfunc:CBase Constructor
CDerived::vfunc:CDerived Constructor
CDerived::vfunc:CDerived Destructor
CBase::vfunc:CBase Destructor
...全文
462 67 打赏 收藏 转发到动态 举报
写回复
用AI写文章
67 条回复
切换为时间正序
请发表友善的回复…
发表回复
breakhigh 2009-03-29
  • 打赏
  • 举报
回复
JF
mouse1984dog 2009-03-17
  • 打赏
  • 举报
回复
jf 顺便温习下
junying2yu 2009-03-17
  • 打赏
  • 举报
回复
up pu
xxweilw 2009-03-17
  • 打赏
  • 举报
回复
jf了,lz多给我点分吧
pengzhixi 2009-03-17
  • 打赏
  • 举报
回复
我觉得这个最大的讨论可能就围绕在构造函数里面调用虚函数吧.
fibbery 2009-03-17
  • 打赏
  • 举报
回复
从表面上来看,这段代码显示了基类和派生类在构造、析构时的顺序。

在声明CDerived类的d1变量时,构造函数从基类CBase开始调用,然后是派生类的构造函数调用。
然而,其实质是什么呢?真的是CBase()先被调用而后再调用CDerived()吗?其实不是的。
因为定义的是CDerived类的变量d1,CDerived()被调用,此时,编译器将CBase()安插在CDerived()的用户代码之前。
这样,CDerived()构造函数在经过编译器处理之后,变成了如下的样子:
CDerived(CDerived * this)
{
CBase(this);
this->vfunc();
}
因此,才出现了基类构造函数的输出在派生类构造函数之前。
析构函数,正好相反,编译器将~CBase()函数的调用,安插在了用户代码之后,所以,基类析构函数的输出在派生类之后。

这个测试,不仅仅是在测试构造和析构的顺序问题,如果仅仅如此,那么没有必要使用虚拟函数类测试,也或者根本没有必
要再使用一个函数专门用来输出信息,直接写在构造和析构函数中就可以了。

看到编译器产生的CDerived类的构造函数,大家也许会发现,CBase()的参数是this,而this是CDerived*类型,那么,
在CBase()构造函数中的调用,应该是这样的:
CBase(CBase * this)
{
this->vfunc();
}
根据多态性,CBase的构造函数也应该输出CDerived构造函数一样的输出,但实际上却不一样,为什么呢?

大家是否想过这个问题?
fairchild811 2009-03-17
  • 打赏
  • 举报
回复
多态性
wendyncu 2009-03-17
  • 打赏
  • 举报
回复
老觉得主函数少了点东西,顺便接分哦
Qlaiaqu 2009-03-17
  • 打赏
  • 举报
回复
我也是来接份的
ctan 2009-03-17
  • 打赏
  • 举报
回复
楼主代码是一个很基本的基类和派生类的构造函数和析构函数的调用的先后次序问题
yangch_nhcmo 2009-03-17
  • 打赏
  • 举报
回复
抱歉,上面打错字了,析构打成虚构了
yangch_nhcmo 2009-03-17
  • 打赏
  • 举报
回复

#include <iostream>
#include <string>

class CBase
{
public:
CBase()
{
vfunc("CBase Constructor");
}
virtual ~CBase() //增加virtual,如果不增加virtual,delete 基类指针时不会调用派生类虚构函数
{
vfunc("CBase Destructor");
}
virtual void vfunc(std::string str)
{
std::cout<<"CBase::vfunc:"<<str<<std::endl;
}
};

class CDerived: public CBase
{
public:
CDerived()
{
vfunc("CDerived Constructor");
}
~CDerived()
{
vfunc("CDerived Destructor");
}
virtual void vfunc(std::string str)
{
std::cout<<"CDerived::vfunc:"<<str<<std::endl;
}
};

int main()
{
CBase *p = new CDerived(); //先调用基类构造函数,再调用派生类构造函数
//CDerived d1;
p->vfunc("test"); //多态,调用派生类的vfunc()

delete (CBase *) p; // 先调用派生类虚构函数,再调用基类虚构函数;

return 0;
}



liaoweixiaoyu 2009-03-17
  • 打赏
  • 举报
回复
学习
lingyin55 2009-03-17
  • 打赏
  • 举报
回复
jf
Treazy 2009-03-17
  • 打赏
  • 举报
回复
我只想接分,不想谈问题
liudafei1 2009-03-17
  • 打赏
  • 举报
回复
mark
guocai_yao 2009-03-17
  • 打赏
  • 举报
回复
mark
henry19850318 2009-03-17
  • 打赏
  • 举报
回复
只是为了验证先构造的后析构............
xinhua0910 2009-03-17
  • 打赏
  • 举报
回复
接分
Cpp权哥 2009-03-17
  • 打赏
  • 举报
回复
你的测试代码中没有测试到虚函数,没有测试到多态调用与直接调用。
你可以在程序中加上一个基类指针,让它指向子类对象,尝试通过它分别调用父类和子类中的虚函数。
加载更多回复(47)

65,210

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧