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

类别:VC语言 点击:0 评论:0 推荐:

  .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++ 托管扩展编程)

  

[email protected]

释雪

2002.11.30

本文地址:http://com.8s8s.com/it/it2127.htm