c++类的继承与派生 程序分析

c++类的继承与派生 程序分析,第1张

//

1,

代码风格不好,阅读性不好,扩展性不好

2,

理解这段代码,需要掌握

类的继承派生,虚基类,构造及析构

(没有函数重载,没有构造函数重载,有更烦)

3,

我把代码重新排版一下,便于阅读

我代码很整齐的,该死的百度,乱排版

介绍一下个人方法:

在阅读类的说明时候,自己在草稿上写下:

A(int a):x(a)

A(a)

A Aobj(c)

B(int a,int b,int c):A(a),y(c),Aobj(c)

A(0)

virtual A(a)

A Aobj(c)

B(a,b,c)

C(int a,int b,int c):B(a,b,c),A(0)

A(c)

virtual A(a)

virtual A(0)

A Aobj(c)

B(a,b,c)

C(a,b,c)

D(int a,int b,int c):C(a,b,c),A(c)

4,

上面有四段,每段是一个类

拿最后一段来说明

D直接继承了C,A;C直接继承了B,A;B直接继承了A

所以D继承了ABC,而且父类树要在草稿上画好

用类D来说明对象时,分配存储空间时候

会分析派生继承树,从最上层开始构造

a,b,c是值传递

先构造A(c) D直接构造了虚基类

再构造A(a) 这是有virtual虚基类说明,所以不构造了

再构造A(0) 这是有virtual虚基类说明,所以不构造了

再构造A Aobj(c) 注意Aobj是对象,要构造,不是虚基类

再构造B(a,b,c)

再构造C(a,b,c)

最后构造D(int a,int b,int c)

析构的时候顺序就反过来

记住虚基类只构造一次,而且是D直接给值

如果D中没有A(c),也不会用BC中的初始化A来构造

而会直接用A中的缺省构造函数了构造

你的A种没有缺省构造函数了构造,所以D中如果没有A(c)会错

5,

(构造析构没说明系统会自动给默认的)

那么派生之后D的成员有哪些呢

dAobjf

dAobjx private B private A 访问

dAobjA

dAobj~A

ddisplay

df

dx private A 访问

dy private B 访问

A ~A

B ~B

C ~C

D ~D

ABC的成员自己写吧,草稿纸用去不少啊

//

好了,下面分析main

D d(7,8,9);

说明对象d,分配给存储空间

A(9)

virtual A(a)

virtual A(0)

A Aobj(9)

B(7,8,9)

C(7,8,9)

D(7,8,9)

做什么事情很简单了吧,就是构造函数{}中的事情:

A(9) cout<<"A constructor"<<9<<endl;

A Aobj(9) cout<<"A constructor"<<9<<endl;

B(7,8,9) cout<<"B constructor"<<endl;

C(7,8,9) cout<<"C constructor"<<endl;

D(7,8,9) cout<<"C constructor"<<endl;

值的传递也会在构造的时候进行

你要在草稿上写下这时候d的数据成员

dx=9

dy=9

dAobjx=9

其他是函数成员

df();

A和B中都有f();从树子到树父去找到调用

(分析的时候注意f()是谁在改变谁的)

找到B的f()函数,调用A::f();Aobjf();return ++y;

A::f(); 之后输出9,dx=10

Aobjf(); 之后输出9,dAobjx=10

return ++y; 之后dy=10

ddisplay();

只有一个display()

调用cout<<A::f()<<"\t"<<Aobjf()<<"\t"<<f()<<endl;

从后往前:

f() 调用B的f()函数A::f();Aobjf();return ++y;

A::f(); 输出10,dx=11

Aobjf(); 输出10,dAobjx=11

return ++y; dy=11

准备输出dy值11

Aobjf() Aobj是A类,调用A的f()

输出11,dAobjx=12

准备输出dAobjx值12

A::f()

输出11,dx=12

准备输出dx值12

然后输出12 12 11

//

总结

构造从树父到树子,其余从树子到树父

虚基类构造只一次

//

#include<iostream>

using namespace std;

class A

{

private:

int x;

public:

A(int a):x(a)

{

cout<<"A constructor"<<x<<endl;

}

int f()

{

cout<<x<<endl;

return ++x;

}

~A()

{

cout<<"destructor A"<<endl;

}

};

class B:public virtual A

{

private:

int y;

A Aobj;

public:

B(int a,int b,int c):A(a),y(c),Aobj(c)

{

cout<<"B constructor"<<y<<endl;

}

int f()

{

A::f();

Aobjf();

return ++y;

}

void display()

{

cout<<A::f()<<"\t"<<Aobjf()<<"\t"<<f()<<endl;

}

~B()

{

cout<<"destructor B"<<endl;

}

};

class C:public B

{

public:

C(int a,int b,int c):B(a,b,c),A(0)

{

cout<<"C constructor"<<endl;

}

};

class D:public C,public virtual A

{

public:

D(int a,int b,int c):C(a,b,c),A(c)

{

cout<<"D constructor"<<endl;

}

~D()

{

cout<<"destructor D"<<endl;

}

};

int main()

{

D d(7,8,9);

df();

ddisplay();

return 0;

}

随着Windows XP和Office XP的推出,兼具华美和清爽气质的Office XP界面风格也逐渐取代了Windows经典界面风格而成为了当前应用程序的流行“时装”,因而如何使自己的应用程序拥有Office XP风格的界面也成为了广大程序员感兴趣的问题。为此法国程序员Jean-Michel LE FOL针对于Visual C++编写了CMenuXP类,使用CMenuXP类就可以轻松使自己的应用程序拥有Office XP风格的界面。下面我就以详细介绍一下使用CMenuXP的步骤。

首先新建一个名叫“SDIXP”的单文档的MFC应用程序。在我们能使用CMenuXP之前,必须进行一下几步 *** 作:

1将CMenuXP的源文件和头文件所在的文件夹(一般放在名叫“Tools”)放到SDIXP源文件的目录下。

2将Visual C++切换到“文件视图(FileView)”,加入CMenuXP的源文件和头文件。具体可以这样进行:在FileView的树状目录下,展开SDI files,在Source Files目录上点击右键,创建新目录(“New Folder…”),不妨取名叫“Tools”,再在Tools目录上点击右键,选择加入文件(“Add Files to Folder…”),将Tools文件夹下的所有源文件(cpp)全部加进来。同理,在文件视图的Header Files目录下新建一个叫做“Tool Headers”,再将Tools文件夹下的所有头文件(h)全部加到Tool Headers目录里。

3(1)在控制菜单的类的头文件(对于SDI程序通常是MainFrmh)里加入所需要的CMenuXP类的头文件名:

#include “Tools/MenuXPh“

#include “Tools/ToolBarXPh“

#include “Tools/StatusBarXPh“

#include “Tools/ComboBoxXPh“

再在MainFrmh里加入下面的宏:DECLARE_MENUXP()

上述语句可以加在CMainFrame类声明里的宏定义“DECLARE_MESSAGE_MAP()”的后面。

(2)在控制菜单的类的源文件(MainFrmcpp)里加入:IMPLEMENT_MENUXP(类名, 基类名);

对于SDI工程就是 IMPLEMENT_MENUXP(CMainFrame, CFrameWnd);

上述语句加在CMainFrame开头的“IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd)”后面。

(3)接着继续在消息映射里如下加入:

BEGIN_MESSAGE_MAP(className, baseClass)

//

ON_MENUXP_MESSAGES() //加入这一行

END_MESSAGE_MAP()

(4)在继承于CWinApp的类(这里就是CSDIXPApp)中的InitInstance()函数里加入:

CMenuXP::InitializeHook();

可以加在“AfxEnableControlContainer();”语句后面。

然后再为CSDIXPApp类重载ExitInstance()函数,可以在“类视图(ClassView)”里点右键加入。再在ExitInstance()函数里加入:

CMenuXP::UninitializeHook();

以上步骤做完之后可以按F7编译一下,如果一切没有问题我们就可以开始使用CMenuXP来美化我们的菜单和工具栏了。

首先,我们来将菜单和菜单项XP化。这很简单,只要在CMainFrame:: OnCreate()函数里加入:

CMenuXP::UpdateMenuBar(this);

CMenuXP::SetXPLookNFeel(this);

就OK了。现在你编译运行一下,看看你的程序菜单是不是改头换面了?

如果你想为自己菜单项定制图标,我们可以用CMenuXP::SetMenuItemImage (UNIT nID, HIMAGELIST hImgList, int nIndex)函数来实现。为此,我们新建一个菜单“水果”和菜单项“苹果”(ID设置为ID_MENUITEM_APPLE),打开ClassWizard为ID_MENUITEM_APPLE添加消息处理函数OnMenuitemApple()。然后再导入一个位图资源“APPLEbmp”,其ID设置为IDB_APPLE。

接着我们为CMainFrame添加CImageList类型的成员变量m_imgList,再在CMainFrame:: OnCreate()函数的“CMenuXP::SetXPLookNFeel (this);”后面加入:

m_imgListCreate(IDB_APPLE, 0, 0, RGB(192,192,192));

CMenuXP::SetMenuItemImage(ID_MENUITEM_APPLE, m_imgList, 0);

其中m_imgListCreate()函数中的第2,3个参数是位图文件的图像拷贝的左上角坐标,最后一个参数是图像的背景色。建议使用16×16的位图。SetMenuItemImage()函数的最后一个参数指的是m_imgList的中元素的索引,这里因为m_imgList只包含一个位图,故取零。编译后运行,看看“水果|苹果”菜单项前面是不是多了一个苹果的图标?

下面我们在将使工具栏和状态栏XP化,这个更加easy了。只要将CMainFrame类声明中的

CStatusBar m_wndStatusBar;

CToolBar m_wndToolBar;

变成

CStatusBarXP m_wndStatusBar;

CToolBarXP m_wndToolBar;

就搞定了!不信,你编译运行一下看看

CMenuXP还可以将按钮和下拉列表框变成Office XP风格的。为此我们新建一个对话框IDD_APPLE。OK和Cancel按钮保持不动,我们只增添一个下拉列表框控件IDC_COMBO1。然后按Ctrl+W打开ClassWizard为该对话框新建一个CAppleDlg类。再在ClassWizard中的Member Variable里为IDC_COMBO1添加Control类型的变量m_cmbx1。接着为CAppleDlg重载OnInitDialog()用以初始化控件:

BOOL CAppleDlg::OnInitDialog()

{

CDialog::OnInitDialog();

m_cmbx1AddString(“红苹果“);

m_cmbx1AddString(“青苹果“);

return TRUE;

}

然后在“苹果”菜单项的消息处理函数中使苹果对话框d出:

void CMainFrame::OnMenuitemApple()

{

// TODO: Add your command handler code here

CAppleDlg dialog;

dialogDoModal();

}

如果这时编译运行,就会看到打开“水果|苹果”菜单项后d出一个对话框,但上面的控件还不是Office XP风格的,下面我们就着手使其XP化,其实这同样也是很easy的!

先在AppleDlgh文件中包含“Tools/ComboBoxXPh“和“Tools/ButtonXPh“,再找到定义m_cmbx1的位置,将 CComboBox m_cmbx1; 变成 CComboBoxXP m_cmbx1;

这样下拉列表框就有XP风格了,不信你编译运行试试。关于OK和Cancel按钮就稍微特殊一点,因为它们是直接用IDOK和IDCANCEL标识的默认按钮,但为了使它们XP化,我们还是得为这两个按钮添加控制变量。因此,在CAppleDlg类的声明中添加:

CButtonXP m_btnOK;

CButtonXP m_btnCancel;

再在CAppleDlg::DoDataExchange()函数中添加数据交换:

DDX_Control(pDX, IDOK, m_btnOK);

DDX_Control(pDX, IDCANCEL, m_btnCancel);

这样,OK和Cancel按钮也都XP化了。大家编译运行一下,看看效果怎么样。

总之,使用Jean-Michel LE FOL的CMenuXP给用Visual C++开发的应用程序换上Office XP风格的界面还是很不错的, *** 作起来也比较简便。不足的就是其他许多控件,如文本框等还是没有Office XP风格,这就期待着原作者以及我们大家继续完善CMenuXP类。

(24)[答案]A

[考点]程序设计基础

[评析]

结构化程序设计中力求程序的可读性(如代码清晰,结构明了,附加注释……),故D错;

如果程序写的都是错的,谈何风格?如果符号名的命名不符合语法,编译会报错,也是很基本的错误,B错;

追求程序的可读性要高于执行效率,C错。

以上就是关于c++类的继承与派生 程序分析全部的内容,包括:c++类的继承与派生 程序分析、在VC中用CMenuXP使应用程序拥有OfficeXP风格、(24) 对建立良好的程序设计风格,下面描述正确的是______。等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/9617465.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-30
下一篇 2023-04-30

发表评论

登录后才能评论

评论列表(0条)

保存