动态网站制作指南 [  QQ表情  ]
[ 投票调查 ]
[ 企业邮箱 ]
[ 网站空间 ]
网络编程 | 站长之家 | 网页制作 | 图形图象 | 操作系统 | 冲浪宝典 | 软件教学 | 网络办公 | 邮件系统 | 网络安全 | 认证考试 | 系统进程
ASP源码 | .Net源码 | PHP源码 | JSP源码 | JAVA源码 | CGI源码 | VB源码 | C++源码 | Delphi源码 | PB源码 | VF源码 | 汇编 | 服务器
电脑书籍下载:程序设计书籍 | 数据库教程书籍 | 平面与多媒体书籍 | 网络通讯书籍 | 系统管理书籍 | 网络安全书籍 | 认证考试书籍
Firefox | IE | Maxthon | 迅雷 | 电驴 | BitComet | FlashGet | QQ | QQ空间 | Vista | 输入法 | Ghost | Word | Excel | wps | Powerpoint
asp | .net | php | jsp | Sql | c# | Ajax | xml | Dreamweaver | FrontPages | Javascript | css | photoshop | fireworks | Flash | Cad | Discuz!
当前位置 > 网站建设学院 > 网络编程 > C/C++教程
Tag:注入,存储过程,分页,安全,优化,xmlhttp,fso,jmail,application,session,防盗链,stream,无组件,组件,md5,乱码,缓存,加密,验证码,算法,cookies,ubb,正则表达式,水印,索引,日志,压缩,base64,url重写,上传,控件,Web.config,JDBC,函数,内存,PDF,迁移,结构,破解,编译,配置,进程,分词,IIS,Apache,Tomcat,phpmyadmin,Gzip,触发器,socket
网络编程:ASP教程,ASP.NET教程,PHP教程,JSP教程,C#教程,数据库,XML教程,Ajax,Java,Perl,Shell,VB教程,Delphi,C/C++教程,软件工程,J2EE/J2ME,移动开发
文章搜索服务
邮件订阅
输入你的邮件地址,
你将不会错过任何关于:
[ C/C++教程 ]的信息



本月文章推荐
.在CB中用socket api来写网络通讯.
.怎样隐藏应用程序的任务栏图标.
.C/C++指针学习的两个经典实例.
.C++ SDK+Symbian开发入门之运行.
.C++计算四则表达式的模板.
.重载CreateParams实现无标题栏的.
.怎样用C语言编写一个DOS下的中断.
.More Effective C++:类型转换.
.用C++实现简单的文件I/O操作.
.C++中结构体的的慨念和使用方法.
.8 Quen.
.C程序开发经典实例之1.
.C++ Builder 初学问与答 (九).
.用游戏串起程序员的基本功之一.
.C语言编程常见问题解答之调试.
.VC打造自己特色的屏幕保护.
.C++ Builder 控制窗体.
.MCI(媒体控制接口)相关知识.
.BCB6命令行工具简介.
.链表的c语言实现(四).

在可管理C++中封装值类型

发表日期:2008-3-8 |



  有些时候,一些很简单的事情实现起来并不轻易。例如,我们想让一个变量值显示在屏幕上。也许你知道在C++中怎么做,但在VC++6中,要用下面的方法实现:

int x = 3; cout << "x is " << x << endl;

就这么简单。不论你学的“C++入门课”怎样,我打赌你能发现的与这两行代码相似的东西不足你在课程中学到的10%,对吗?

输出到屏幕


现在,假如要在VC++.NET中创建可治理的C++程序该怎么做?下面是我创建的main():

int _tmain(void) { // TODO: Please replace the sample code below // with your own. Console::WriteLine(S"Hello World"); return 0; }

现在你可以把应用Cout的代码拷贝到main()中,在加入了include声明后,就可以执行:

#include <iostream.h> // ... Console::WriteLine(S"Hello World"); int x = 3; cout << "x is " << x << endl;

这时,你会看到一个警告:

warning C4995: '_OLD_IOSTREAMS_ARE_DEPRECATED': name was marked as #pragma deprecated

解决的方法:借用STL中的IO流的代码,并且导入std 名称空间:

#include <iostream> using namespace std;

现在编译并运行这段代码。但是让我不解的是,在程序中发现作为cout应用的Console::WriteLine()。另外,Console::WriteLine很整洁。就像printf,它在字符串中使用占位符显示变量值应该放到哪。下面是一个c#控制程序中的代码:

int x = 3; Console.WriteLine("x is {0}",x);

{0}是一个占位符,第二个参数的值截止到占位符出现的位置。因此我想像在c#中一样,在可治理的c++程序中一直使用Console::WriteLine。但是假如你把代码直接拷到c++程序中,并将.改为::,程序不能通过编译。错误显示为:

error C2665: 'System::Console::WriteLine' : none of the 19 overloads can convert parameter 2 from type 'int' boXPin.cpp(7): could be 'void System::Console::WriteLine( System::String __gc *,System::Object __gc *)' boxpin.cpp(7): or 'void System::Console::WriteLine( System::String __gc *,System::Object __gc * __gc[])' while trying to match the argument list '(char [9], int)'

现在,我固执地希望c++能做其他.net语言能做的所有事情,甚至更多。为什么这么简单的办法行不通?没别的办法,看看错误提示吧。我给第二个参数赋一个整数值,它就像一个指针。事实上,是一类指向System::Object的指针(当然,还有由其衍生出的类),一类指向__gc object的指针。而这个整数值两种都不是。你可以试着传递&x值,而非x,那样至少是一个指针,但还是无济于事。

WriteLine()需要的是一个指向对象的指针。你不能直接将整数值传递给WriteLine(),因为它是(处于整体性的考虑)用来处理指向垃圾收集对象的指针,而不是其他的。为什么?基本类库中的所有内容都是针对对象设计的,因为他们都可有成员函数——并不是所有的.net语言都支持模式化或是过载模式化运算符的思想。比如,由System::Object继续下来的所有对象都有一个ToString() 方法。你不想为一个非对象的整数写一个类,然后又写一个ToString()来处理它,在每次将它传递给像WriteLine()基本类库中的方法的时候,还要把它放入(或取出)。这时,你怎么把整数传递给WriteLine()?

_box要害字


可治理的c++也被称为c++可治理的扩展。扩展是指额外要害字,都是以双下划线开头,并被增加到语言中。和其他所有以双下划线开始的要害字一样,他们的编译器是特定的——不要在vc++6和其他产商的编译器中试用。在编译WriteLine() 时,你只会在错误信息中看到_gc。它代表着垃圾收集并且指向一个依靠堆栈类型,并由运行时间控制的对象。_box要害字可以解决我在上面提到的,如何将整数传给基本类库方法,它得到的是System::Object _gc而不是一个整数。下面是它的使用方法:


Console::WriteLine("x is {0}",__box(x));
封装一个值的类别就是把值放到一个临时对象(这个对象是System::Object继续类的实例,存于垃圾收集堆)中,然后再把临时对象的地址传递给方法调用。原有变量中所有的东西都被拷入临时对象中,这个对象提供WriteLine()需要的所有功能。__box要害字意味着值类型和可治理类型都适合于基本类库提供的所有服务。

封装的替代办法


装箱答应你在期待指向可管指针的基本类库的方法中使用值类型和可治理类型。这自然产生了一个问题:在值类型和可治理类型中究竟有什么区别?可治理类型存于垃圾收集堆中,并且被运行时间所治理。下面是一个例子:

__gc class Foo { // internals omitted }; // ... Foo* f = new Foo();

FOO类是可治理类型。你不能在堆栈上创建Foo f2;这样的实例:

假如你已经有一个类(也许是从以前的.net程序中获得),它一定不是一个可治理类型。它没有_gc要害字。当然,你可以加上要害字(假设类符合成为一个可治理类型的所有条件),但接下来你要找到所有创建类实例的地址,还有保证他们是在堆上创建的实例,比如:

OldClass* poc = new OldClass(); //maybe some parameters //to the constrUCtor

你要记住,在代码中调用类方法的每一处,都要把.改为->。保持原来的类型,这样你可以按照你的意愿在堆栈或未治理的堆上分配实例:

class notmanaged { private: int val; public: notmanaged(int v) : val(v) {}; }; // ... notmanaged nm(4); notmanaged *p = new notmanaged(5);

这并不难:这就是还没发布加入可治理扩

上一篇:C++/CLI思辨录之再谈继承 人气:171
下一篇:在Windows NT 下实现对I/O地址的访问 人气:221
浏览全部C/C++的内容 Dreamweaver插件下载 常用网页广告代码全集
  最新网站源码 最新软件下载
2008-7-6 飞天论坛FTBBS ASP v6.3 Build 0
2008-7-6 飞天论坛FTBBS ASP v6.3 Build 0
2008-7-6 飞天论坛FTBBS ASP v6.8 Build 0
2008-7-6 讯息内容管理系统 v2.1
2008-7-6 三五电影程序 v2.0
2008-7-6 神鹰腾讯小说小偷 v3.0
2008-7-6 EasyIDE Framework v1.0 Build 2
2008-7-6 品告CMS系统(电影版) v0.9
2008-7-6 QQ自动登录器 C# 源码 v1.0
2008-7-5 AgileMessenger即时通讯工具 v1.
2008-7-5 GoodCalculator2.0版固件计算器
2008-7-5 RepoName源地址搜索工具 v1.21b
2008-7-5 AgileMessenger即时通讯工具 v1.
2008-7-5 TouchCopy多媒体管理软件 v3.13完
2008-7-5 VideosTone视频铃声 v1.1汉化破解
2008-7-5 TouchPad触摸板 v4.44破解版
2008-7-5 VideosTone破解补丁 v1.0
2008-7-5 Feeds GoogleReader客户端 v0.4.3


  发表评论
姓 名: 验证码:
内 容:
[ 汉字翻译拼音 ] [ 广告代码 ] [ 符号对照表 ] [ 进制转换 ] [ 经典小工具 ] [ 个税计算 ] [ 汉字简繁转换 ] [ 普通单位换算 ] [ 公制单位换算 ]
[ 生辰老黄历 ] [ 国内电话区号 ] [ 国家代码与域名缩写 ] [ 文字加密解密 ] [ 健康查询 ] [ 万年历 ] [ 手机号码查询 ] [ ip搜索 ] [ Google PR查询 ]
业务联系 | 广告刊登 | 频道合作 | 投稿荐稿 | 联系方式 | 加入收藏 | RSS订阅
Copyright © 2000-2008 www.knowsky.com All rights reserved | 网络实名:动态网站制作指南 | 沪ICP备05001343号
ホームページ制作 不動産検索システム 求人情報