分享
 
 
 

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

王朝c/c++·作者佚名  2008-06-01
窄屏简体版  字體: |||超大  

有些时候,一些很简单的事情实现起来并不轻易。例如,我们想让一个变量值显示在屏幕上。也许你知道在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);

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

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
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- 王朝網路 版權所有