接触VC(二)

原创 2002年11月26日 09:16:00
 

第二部分    MFC类基础,C++程序编写规范介绍<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

 

由于本文是面对C语言基础的(因为我就是从C学起来的),而MFC是利用C++类技术构建起来的。因此有必要在此为只了解C的朋友们,普及一下C++语言中类的概念。熟悉C++的朋友可以跳本部分。

从总体来说C++是向下兼容C的,你可以很不费力气地将用C编好了的程序拿到C++环境下编译执行。其C++只不过是在C的基础上添加面向对象技术(OOP),也就是类的概念,且值得一提的是C与C++都是由美国的贝尔实验室(在之前我只知道发明过电话)发明的。

什么是类?按一些书本上的定义来说“就是一种复杂的数据类型,它是将不同类型的数据和与这些数据相关的操作封装在一起的集合体。因此,类中的数据具有隐藏性,类还具有封装性。”嗯,类还像上面的那句话一样,具有很强的抽象性。让我来用一个例子来解释类吧。

嗯,我们世界上有一个生物种类叫做鸟,在C++上世界我们也可以制作一个类叫做鸟类。它应该有头,有躯干,有腿,有内脏,还有一个非常重要的翅膀。于是,其类描述如下:

class Aves

{

    char m_strHead[10];

    char m_strTrunk[10];

    char m_strCrura[10];

    char m_strWing[10];

    char m_strBowels[10];

};

哈,这样一个鸟类建立好了,怎么样与C中结构体没什么两样吧。(在C++中struct与class基本上是同义词,过一会儿会说到它们有什么不同的。)如果你想建立一个小鸟的话,不用像C中那样麻烦地打struct Aves XXX,而是直接使用Aves XXX就可以了,不打前面的struct或class。

在人类对鸟类形成概念之前,鸟的翅膀、躯体等等就真的存在了(没有人有疑议吧?),但在人们根本不知道鸟的那对长满羽毛的扑扇扑扇就可以飞的东西叫什么名字,也不会知道翅膀这个词指的是什么意思。现在我们的这个C++鸟类也正处于这个状态,在那些成员变量中没有被赋与任何值。而现实生活中,一个种类中的具体名字是在一个类对象形成初期被命名的,这是一个名词初始化的过程。在C++类中,当建立一个类对象时总也要有一个初始化各成员变量的过程,于是构造函数被引入了。它在一个实例被声明和被建立(这两个有一些区别)时调用。我们的C++鸟类各个成员变量的赋值命名就可以利用它来实现:

class Aves

{

    Aves ()

    {

         strcpy(m_strHead, "Head");

         strcpy(m_strTrunk, "Trunk");

         strcpy(m_strCrura, "Crura");

         strcpy(m_strWing, "Wing");

         strcpy(m_strBowels,”Bowels”);

    }

    char m_strHead[10];

    char m_strTrunk[10];

    char m_strCrura[10];

    char m_strWing[10];

};

瞧,我是怎么在类里面建立一个构造函数的。一个类的构造函数的名字要与其类名同名,且不能有返回值,void也不行。我们在构造函数中,对各个成员函数命名。当Aves bird;时(声明一个bird对象),Aves类的构造函数将会被调用,把bird.m_strHead,bird.m_strTrunk等等成员变量分别赋值为”Head”,”Trunk”。

这样一讲,希望大家对构造函数有了一定的了解了。我们既然有构造函数可以对类成员进行初始化,那么用什么来对类成员销注呢?说白了就是有在建立类对象时调用的函数,什么函数是在类对象被删除时调用的函数呢?那就是析构函数,其命名规则与构造函数是一样的,只不过需要在其函数名前紧加一个~(波浪号),且不能有参数。如我们的类就是~Aves();

至于析构函数具体作用嘛…举个例子来说,当在构造函数中申请了一段内存,我们就必须在析构函数中释放这段内存,否则会内存泄漏。

那么什么时候会引发声明的类对象被删除呢?要解决这个问题,我还需要借用一个叫名域(name space)的概念。当系统执行指针离开声明的类对象所在名域时,就会引发类对象的删除(类型的有效型也可以如此解释)。

而名域这个概念最实称的理解就是一对大括号,在这对括号内的空间就是一个名域。(当然名域其实不是这么简单的。如类本身就是一个名域,还可以自己设定一个名域,用于类型声明设定,可以用已有的类型冲突。名域真实用途是这个。具体含义参见《C++标准库》,图书大厦有侯捷先生的译本)比如:

{//名域1

    char * strValue;

    {//名域2

         Aves bird;

         {//名域3

              strValue=bird.m_strWing;

         }

}//<<就在后大括号这里引发了bird对象的析构函数

strValue=”Blue Atlantis”;

}

这里有3个名域,我在名域2中声明了一只小鸟。因为名域3也被包括在名域2里,所以名域3中的空间也属于名域2,于是在名域3中引用小鸟对象是正确的。当执行指针离开名域2那一瞬,C++系统将会把在名域2中声明的所有变量及对象删除掉。

当对象被删除时,首先会执行析构函数,然后系统再去释放对象所占用的内存空间。

所以当执行到strValue=”Blue Atlantis”;这一句时,这只小鸟就已经不存在,再去引用它就会编译错误。

另外,要讲一讲对象的建立。一种是像变量一样声明建立起来对象,像上面的Aves bird;另一种就是用new语句来建立起来对象。如:

Aves *bird;

bird= new Aves();

new语句跟着一个类的构造函数,它会在内存建立起来一个对象,并把这个对象的指针返回出来。这样建立起来的对象没有名域空间的限制。如果要将这个对象删除掉必须手动的使用delete语句。如:

delete bird;

delete后面跟着指向要删除对象的指针变量。注意,这个指针变量的类型直接影响到对象的删除时所使用的析构函数。所以,什么类型的对象,就要用什么类型的指针来指向删除。

真实的鸟类应该是可以飞翔(绝大部分),可以发出叫声,可以在陆上跑(至少可以跳)。所以我们也应该让我们的鸟类也可以跳,可以飞吧。于是,我要向类中添加成员函数。声明成员函数可以有两种方法,一种是在类的声明体里面,像上面例子中构造函数的声明方法,另一种是在类的声明体外面。外部的表现写法为 返回值  类名::函数名(参数列表)。注意::是由于两冒号组成。

下面的代码就是使用第二种声明方法(当然,两种方法可以混用):

#include <iostream.h>

#include <string.h>

 

class Aves

{  

public:

    Aves ();

    ~Aves ();

    void tweet();

    void run();

    void fly();

    char m_strHead[10];

    char m_strTrunk[10];

    char m_strCrura[10];

    char m_strWing[10];

private:

    char m_strBowels[10];

};

 

Aves::Aves()

{

    strcpy(m_strHead, "Head");

    strcpy(m_strTrunk, "Trunk");

    strcpy(m_strCrura, "Crura");

    strcpy(m_strWing, "Wing");

    strcpy(m_strBowels, "Bowels");

    cout<<"a bird born!"<<endl;

}

 

Aves::~Aves()

{

    cout<<"a bird die!"<<endl;

}

 

void Aves::tweet()

{

    cout<<"jijijijijijiji"<<endl;

}

 

void Aves::run()

{

    cout<<"I can run by "<<m_strCrura<<endl;

}

 

void Aves::fly()

{

    cout<<"I can fly by "<<m_strWing<<endl;

}

 

 

接触VC

 预设目录: 第一部分:WinSDK第二部分:MFC类基础,C++程序编写规范介绍第三部分:MFC基于对话框程序第四部分:Dll动态链接库第五部分:COM组件基础第六部分:COM组件几个常用技术:ID...
  • BlueAtlantis
  • BlueAtlantis
  • 2002年11月29日 10:05
  • 657

(转)[教程] 程序中使用MATLAB编译产生的DLL (VC6.0, MATLAB R2010b, mwArray

最近需要在VC下调用MATLAB的dll,以前没怎么接触过这些,今天特地摸索了一下。主要借鉴的是taohe兄的这篇帖子:http://forum.simwe.com/thread-801187-1-1...
  • u013018721
  • u013018721
  • 2014年10月28日 21:28
  • 880

接触VC,2:1

 第二部分    MFC类基础,C++程序编写规范介绍 由于本文是面对C语言基础的(因为我就是从C学起来的),而MFC是利用C++类技术构建起来的。因此有必要在此为只了解C的朋友们,普及一下C++语言...
  • BlueAtlantis
  • BlueAtlantis
  • 2002年11月26日 09:16
  • 757

接触VC,2:2

接上段. 我们在Ostrich类的基础写了fly(),tweet()成员函数,这是与基类的成员函数名字相同。那么它们将覆盖基类的函数,如果再调用Ostrich类的fly(),tweet()函数的话则会...
  • BlueAtlantis
  • BlueAtlantis
  • 2002年11月26日 09:16
  • 730

接触VC之一:WinSDK

接触VC之一:WinSDK作者:释雪 预设目录:第一部分:WinSDK第二部分:MFC类基础,C++程序编写规范介绍第三部分:MFC基于对话框程序第四部分:Dll动态链接库第五部分:COM组件基础第六...
  • hejianhua
  • hejianhua
  • 2008年12月02日 10:27
  • 694

接触VC 3:2

下面,我们来一个对于对话框非常重要的函数OnInitDialog(),顾名思义这是一个对话框的初始化函数。在对话框创建之后,第一次显示之前调用。BOOL CDialogDlg::OnInitDialo...
  • BlueAtlantis
  • BlueAtlantis
  • 2002年12月09日 10:59
  • 854

接触VC 3:1

 第三部分:MFC基于对话框程序 最近,本人赶时髦,装上了一套Visual Studio.net(不过是盗版,微软挺悲惨的。但如果是正版的话,那悲惨的就不会是微软,而是我了。没钱啊)。安装要2213M...
  • BlueAtlantis
  • BlueAtlantis
  • 2002年12月09日 10:58
  • 941

测试接触电流的一些小常识

1、如何判定自己的仪器是需要按照一类仪器测试还是二类仪器测试呢? Ⅰ类设备 class Ⅰ equipment :不仅依靠基本绝缘进行防触电保护,而且还包括一个附加的安全措施,即把易触及的导电部分连...
  • hiDenise
  • hiDenise
  • 2012年03月28日 09:30
  • 1196

死锁的产生、预防、以及接触方法整理,一目了然

产生死锁的4个必要条件:1.互斥条件 2.请求和保持条件 3.不可抢占 4.循环等待条件 预防死锁主要分为三种:1.破坏请求和保持条件 2.破坏不可抢占条件 3.破坏循环等待条件 避免死锁同样属于事先...
  • hyqsong
  • hyqsong
  • 2016年06月04日 09:13
  • 378

ANSYSworkbench中绑定接触与一个整体的拉伸对比

首先画两个方块,接触微绑定接触,两端加3Mpa载荷,仿真结果如下; 同时绑定接触允许接触面网格不匹配,如下图接触面部分不稳定性较大: 组合为一体(form a ne...
  • ilovemoon10
  • ilovemoon10
  • 2017年07月15日 20:42
  • 620
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:接触VC(二)
举报原因:
原因补充:

(最多只允许输入30个字)