分享
 
 
 

.NET框架以及在C++中的初步应用

王朝vc·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

.NET框架以及在C++中的初步应用

在最新发布的Visual Studio.NET中,随带一种新的技术叫.NET框架。这是一种新的编程机制,微软旨在编程时,提供一个统一的面向对象环境,而且保证对象的透明性(即无论这个对象是否是在本机,Internet上,还是在某个远程环境中);使得在各种软件中的版本冲突达到最小;使得对象达到语言无关性,能够跨语言调用。在.NET框架中,有很大一部分的特性十分类似于JAVA,如:内存管理,类库引用,类似于字节码的MSIL代码等等。

为了充分使用.NET框架,于是微软推出C#.NET这个语言版本。我将使用C#来看一看.NET框架机制。先看一个完整的C#程序:

001:using System;

002:using System.Drawing;

003:using System.Windows.Forms;

004:

005:

007:

008:class Sample

009: {

010: Sample()

011: {

012: m_nMember = 0;

013: }

014:

015: ~Sample()

016: {

017: System.Console.WriteLine ("我被释放掉了.");

018: }

019:

020: delegate void MethodDge (string strMessage);

021:

022: public int Member

023: {

024: set

025: {

026: m_nMember = value;

027: System.Console.WriteLine ("被赋值了。");

028: }

029: get

030: {

031: System.Console.WriteLine ("被取值了。");

032: return m_nMember;

033: }

034: }

035:

036: public void Click(Object sender, EventArgs e)

037: {

038: System.Console.WriteLine ("被单击了!{"};

039: this.Member = 13;

040: System.Console.WriteLine (Member.ToString()+")");

041: }

042:

043: public void OwnMethod (string strMessage)

044: {

045: System.Console.WriteLine (strMessage);

046: }

047:

048: public int m_nMember;

049:

050: public static void Main()

051: {

052: Sample aSample = new Sample();

053: Form Dlg = new Form();

054: EventHandler Click = new EventHandler (aSample.Click);

055: Dlg.Text = "这是一个.NET窗体";

056: Dlg.Click += Click;

057: Dlg.ShowDialog (null);

058: MethodDge InokeMethod = new MethodDge (aSample.OwnMethod);

059: InokeMethod ("这是由委托调用。"+InokeMethod.ToString());

060: }

061: }

这段程序基本上涵盖了.NET大部分特性特性。基本上是很容易看懂的,下面简单讲讲.NET的特性,请对照着例子来看。

.NET类库引用

首先,在Java中是使用import来引用类库的,而C#是使用using,C++使用#using来进行导入类库。并且这些类库都是些被封装在.dll文件中的MSIL代码,叫Microsoft中间语言代码。这些MSIL代码是由.NET 框架实时 (JIT) 编译器来进行编译成本机代码执行的,有点像Java中的解释器解释字节码。我们所编写托管代码(即.NET程序代码)会被编译器编译成MSIL代码,然后由链接器按照PE格式写入.exe或.dll文件当中去。当系统执行文件遇到MSIL时,会使用.NET 框架实时编译器将实时MSIL编译成本机代码,再去执行本机代码。

.NET内存回收

在Java中有一种垃圾回收机制,可以将失去引用的对象自动的释放掉。.NET框架的公共语言运行库也包含了这一功能,我们可以在new完对象以后,无需操心什么时候去delete事了,公共语言运行库会知道什么时候去释放它,且不会影响资源使用效率,也许会有所提高呢。在例子中的主函数里,aSample引用了一个被new出来的Sample对象。在主函数结束时,aSample失去了作用,公共语言运行库当发觉到new出来的那个对象没有人再去引用它,便就立即将它析构了。于是,在主函数结束处,Sample的析构函数被执行了。

.NET类型

1.Object类型

再说说类型,在.NET中,所有类型(包括int,float,double等等)都是派生于Object类的,所以一个Object变量可以被赋与任何类型的值。由于,Object中有关于类型的描述,所以不用担心Object中的类型不明确。如:

int a = 13;

Object b = a;

System.Console.WriteLine (b);

WriteLine会知道b中的值是整型,它的输出仍然是13。

2.值类型与引用类型

在.NET中,类型被分为值类型和引用类型两种(在JAVA同样存在),引用类型行为相当于C\C++中的指针,这种类型包括类类型(用关键字class声明的类型),接口类型(用关键字interface声明的类型),数组类型,委托类型(用关键字delegate声明的类型)。值类型与引用类型的区别示例如下:

class MyClass

{

int a;

}

class Example

{

static void Main (string [] args)

{

int value1 = 12;

int value2 = value1;

MyClass citation1 = new MyClass();

MyClass citation2 = citation1;

value1 = 13;

value2 = 15;

citation1.a = 13;

citation2.a = 15

System.Console.WriteLine (value1.ToSting()+”,”+value2.ToSting());

System.Console.WriteLine (citation1.a.ToString()+”,”+citation2.a.ToString());

}

}

其结果为

13,15

15,15

当一个值类型赋给另一个值类型时,int value2 = value1;是将value1的值复制到value2里去。因此实际存在着两个整型变量。所以当value2值改变时,不会影响到value1的值。而一个引用类型赋给另一个引用类型时,MyClass citation2 = citation1;是将citation2引用成citation1所引用的对象,因此实际只存在一个MyClass对象。citation1和citation2同时指向一个对象,所以当改变citation2.a,citation1.a也同时改变,它们两个是同一个对象。这就是引用类型和值类型的区别,这是.NET中一个比较重要的概念。不过,这在C\C++中关系不大,因为.NET在C++中是用指针来达到引用的概念的(虽然C++中有自己的引用语法),我们仍然可以不使用指针,将类当成值类型来用。

如在C++中的Object __gc * Target相当于C#中的Object Target;

[C#]

Object Target = new Object();

Target.ToString();

[C++]

Object __gc * Target = new Object();

Target->ToString();

两者是等效的。

在C++中__gc表示为托管类型(即.NET类型)。

3.委托类型

在.NET中,委托的行为与C\C++的函数指针相同。如第一个例子中的EventHandler, MethodDge都是委托类型。不同的是,MethodDge是我们自己定义的委托类型,EventHandler是系统程序集定义的委托类型。一个委托类型是这么声明的:

[C#]

delegate 返回值 类型名 (参数列表);

[C++]

__delegate 返回值 类型名 (参数列表);

请看示例的第20行。

一个委托对象是这么声明的:

[C#]

委托类型名 委托对象名 = new (对象.方法)

[C++]

委托类型名 * 委托对象名 = new (对象指针,&(类::方法))

请看示例的第54行和第58行。

当调用委托对象,就等同于调用被引用的函数

[C# & C++]

委托对象名(参数列表);

请看示例的第59行。

而且委托类型支持累加(+=)与累减(-=),当调用委托对象时,效果是累加起来所有委托对象的同时被调用;

[C# & C++]

委托对象名 += 委托类型对象名;

委托对象名 -= 委托类型对象名;

请看示例的第56行。

委托对象主要用在事件上。事件,在Java是利用接口来实现的,.NET框架是由委托对象来实现的。在每个有事件的类中都有几个事件委托对象(EventHanlder类型的,其中有两个参数是Object sender,EventArgs e)的属性与之事件相对应。如有支持单击事件则,该类就肯定有一个名为Click的委托对象属性。当类对象有单击事件产生,则就调用这个委托对象:

if (Click != null)

Click (this, e);

如果想要订阅这份事件,则可以累加上自己的委托对象,取消订阅则累减去自己的委托对象。

第一个例子中的

.NET的类中

1.属性

在第一个例子中,类Sample有一个Member成员的声明。这是一个属性的声明。当Member被取值时调用get程序块返回一个整型值;当Member被赋值时调用set程序块,在C#中参数被隐式声明为value。

在C++中是用__property来声明的

[C++]

__property 类型 get_属性名();//赋值器

__property void set_属性名(类型 value);//取值器

请看示例的第22到34行。

2.不能实例化的类

使用关键字abstract来显示声明这个类为抽象类,不管它是否有纯虚函数。当类被声明为抽象类后,它就不允许实例化出类对象。声明方法如下:

[C#]

abstract class 类名

{

....

}

[C++]

__abstract __gc class 类名

{

...

};

在C++中__gc表示为托管类型(即.NET类型),__nogc显示声明类为非托管类型(即普通的C++类)

3.不能当做基类的类

使用关键字sealed可将类显示声明为封装类。当类被声明为封装类后,不允许有任何类以它为基类。声明方法如下:

[C#]

sealed class 类名

{

....

}

[C++]

__sealed __gc class 类名

{

...

};

以上就是.NET行为上的特性,下面将第一个例子翻成C++托管程序代码,功能效果与C#程序相同:

#using <mscorlib.dll>

#using <System.dll>

#using <System.Drawing.dll>

#using <System.Windows.Forms.dll>

using namespace System;

using namespace System::Windows::Forms;

__gc class Sample

{

public:

Sample(void)

{

m_nMember = 0;

}

~Sample(void)

{

System::Console::WriteLine ("我被释放掉了.");

}

__delegate void MethodDge (String * strMessage);

__property void set_Member (int nValue)

{

m_nMember = nValue;

System::Console::WriteLine ("被赋值了。");

}

__property int get_Member (void)

{

System::Console::WriteLine ("被取值了。");

return m_nMember;

}

void Click(Object * sender, EventArgs * e)

{

System::Console::WriteLine ("被单击了!");

System::Console::WriteLine ("{");

Member = 13;

System::Console::WriteLine (Member.ToString());

System::Console::WriteLine ("}");

}

void OwnMethod (String * strMessage)

{

System::Console::WriteLine (strMessage);

}

int m_nMember;

};

void main ()

{

Sample * aSample = new Sample();

Form * Dlg = new Form();

EventHandler * Click = new EventHandler (aSample,Sample::Click);

Dlg->Text = "这是一个.NET窗体";

Dlg->Click += Click;

Dlg->ShowDialog (0);

Sample::MethodDge * InokeMethod = new Sample::MethodDge (aSample,Sample::OwnMethod);

InokeMethod (String::Concat ("这是由委托调用。",InokeMethod->ToString()));

}

第一行的#using <mscorlib.dll>是公共运行库.

若要在Visual C++.NET上编译通过,请先将项目属性页上的C\C++中常规里的编译为托管设置成为程序集支持。

具体类库应用请查看MSDN.NET上的.NET框架.(.NET框架->参考->类库)

C++的扩展托管请查看MSDN.NET上的Visual C++.NET.( Visual C++.NET->C++ 托管扩展编程)

Blue_Atlantis400@hotmail.com

释雪

2002.11.30

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有