Pro visual c++/cli and .net 2.0 platform2 学习笔记(8第三章 面向对象的C++/CLI===1)

 
第三章 面向对象的C++/CLI
这章只谈托管的类型:ref class/struct value/class/struct 
非托管类型:class struct 第20,21章讲
ref class:ref关键词,指示类在托管堆上。为了与c++兼容,c++/cli缺省认为class在crt堆上。(另:在托管扩展C++上,关键词是__gc//好难看)
ref class的好处:
    垃圾处理
    从.net基类继承(当然是没有被sealed),如果没指定基类,自动继承于System::Object
    能在.net的集合类中应用
    拥有继承多个托管接口的能力
    能有属性成员
    能含有指向非托管类的指针。(注意:这是unsafe的)
缺点:(对C++程序员)
只允许单继承(但允许多接口继承)
不允许继承自/或派生出非托管类型
不支持友元
不能重载gcnew或delete(这本身就与ref的本意相冲突)
必须public继承
不能用sizeof或offsetof操作符(因为句柄不支持数学运算,所以他们也没什么用)
指针算法不被句柄支持(内存泄漏和非法内存访问的根源)
sealed不能被继承的类。
指向对象的句柄:句柄在栈中指向所引用的对象。
注意:如果引用对象包含有未托管的资源,CLR就会保留这个对象不定的时间(不一定永不释放)。
         应用基于COM的ADO就是这种情况的典型例子。这也是托管扩展c++的主要问题之一。不过 
         deterministic析构子能帮助减轻这些问题。
为什么句柄不支持指针运算(他们好像没什么危害):因为CLR会重定位对象。
静态成员函数:只能使用静态成员变量,自然也不能为虚(因为虚是依赖对象实例的)。
ref class 的构造函数
构造函数被用来初始化成员变量,两种方法:在构造器中初始化(用在一个类的实例只被初始化一次);或定义一个初始化函数并用构造器调用它(用在类被重用,需要重新初始化)。
ref class的构造器同非托管类的构造器有所不同,它首先初始化所有的成员变量为0或相当于0(例如:DateTime类型,被初始化为 1/1/0001 12:00:00)的值,然后再调用构造器内的语句。
如果没定义构造函数,编译器会为你建一个,他调用父类的构造函数,并初始化自己的成员为0。
如果你定义了构造函数,那编译器就不会为你建构造函数了。因此,如果你定义了一个带参数的构造函数,而又想无参的建立对象,那么你必须自己建立缺省的构造函数。
拷贝构造函数 :注意: & 变为了 %
静态构造函数:在c++中初始化静态成员非常笨的,在类内定义,在类外初始化。c++/CLI可以在 
          类内直接赋值。但是如果想做的不仅仅是简单的赋值呢?c++/CLI提供了静态构造函数。
静态构造函数的目的就是初始化静态成员变量(不仅仅局限于赋值)。类内有静态成员变量静态构造函数才有意义/*静态方法才有意义*/。
什么时候调用静态构造函数是不确定的,但是可以确保在类实例被创建前和引用静态成员前被创建。
静态成员可以在定义时被初始化,但静态构造函数中的操作会覆盖它。
静态构造函数不能有参数。//象缺省构造函数不被显式调用
析构函数
目的:1,释放用new或gcnew分配的内存,2,释放托管的或未托管的系统资源(容易被忽略)。在托管扩展c++中,只能释放托管内存和托管的系统资源,如想释放未托管的的内存和系统资源必须有程序员继承.net的IDisposable接口。
delete:立即释放,deterministic清除。也可以不调用它,又垃圾处理来决定什么时候清除(大多数情况这更好)。
注意:为了应用delete,析构函数必须是public。//delete调用析构函数。
清理托管资源和清理内存一样。
清理非托管资源(文件句柄,内核对象,数据库对象)有点讨厌。因为你不特意编写代码关闭这些资源,直道程序退出他们不会被关闭(有时需要重启才能关闭)。靠!!!
奇怪为什么CLR没有提供清楚的清除非托管资源的机制,而需要程序员自己来做。典型的做法是把清楚资源的代码放在Dispose()方法中(IDisposable接口的),然后当资源不用时,调用Dispose()。有点麻烦,不是吗?不过这是托管扩展C++中的事了。在C++/CLI中情况好多了。delete自动实现了IDisposable接口。这样你只需要在你的析构函数中清理未托管的资源,然后用delete。
不过还有问题:如果忘记调用delete怎么办?答案是:谁让你忘了呢,自己负责吧!
幸运的是这不是最终的答案:C++/CLI提供了垃圾清理的接口:Finalize析构函数(CLR自动调用);语法!代替~;并且必须为protected。它用在当你不介意什么时候释放和你忘记释放未托管资源的时候。
通常的做法是在析构函数中释放托管和未托管的资源,在Finalize析构函数中释放未托管资源。(这会产生重复的代码,当然也可以放在一个函数中减轻这种重复)。
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值