分类: C/C++
2008-04-14 23:37:50
作者:李阳编译 来源:赛迪网 | ||
| ||
有些时候,一些很简单的事情实现起来并不容易。例如,我们想让一个变量值显示在屏幕上。也许你知道在C++中怎么做,但在VC++6中,要用下面的方法实现:
就这么简单。不论你学的“C++入门课”怎样,我打赌你能发现的与这两行代码相似的东西不足你在课程中学到的10%,对吗?
现在,如果要在VC++.NET中创建可管理的C++程序该怎么做?下面是我创建的main():
现在你可以把应用Cout的代码拷贝到main()中,在加入了include声明后,就可以执行:
这时,你会看到一个警告:
解决的方法:借用STL中的IO流的代码,并且导入std 名称空间:
现在编译并运行这段代码。但是让我不解的是,在程序中发现作为cout应用的Console::WriteLine()。另外,Console::WriteLine很整洁。就像printf,它在字符串中使用占位符显示变量值应该放到哪。下面是一个c#控制程序中的代码:
{0}是一个占位符,第二个参数的值截止到占位符出现的位置。因此我想像在c#中一样,在可管理的c++程序中一直使用Console::WriteLine。但是如果你把代码直接拷到c++程序中,并将.改为::,程序不能通过编译。错误显示为:
现在,我固执地希望c++能做其他.net语言能做的所有事情,甚至更多。为什么这么简单的办法行不通?没别的办法,看看错误提示吧。我给第二个参数赋一个整数值,它就像一个指针。事实上,是一类指向System::Object的指针(当然,还有由其衍生出的类),一类指向__gc object的指针。而这个整数值两种都不是。你可以试着传递&x值,而非x,那样至少是一个指针,但还是无济于事。 WriteLine()需要的是一个指向对象的指针。你不能直接将整数值传递给WriteLine(),因为它是(处于整体性的考虑)用来处理指向垃圾收集对象的指针,而不是其他的。为什么?基本类库中的所有内容都是针对对象设计的,因为他们都可有成员函数——并不是所有的.net语言都支持模式化或是过载模式化运算符的思想。比如,由System::Object继承下来的所有对象都有一个ToString() 方法。你不想为一个非对象的整数写一个类,然后又写一个ToString()来处理它,在每次将它传递给像WriteLine()基本类库中的方法的时候,还要把它放入(或取出)。这时,你怎么把整数传递给WriteLine()?
可管理的c++也被称为c++可管理的扩展。扩展是指额外关键字,都是以双下划线开头,并被增加到语言中。和其他所有以双下划线开始的关键字一样,他们的编译器是特定的——不要在vc++6和其他产商的编译器中试用。在编译WriteLine() 时,你只会在错误信息中看到_gc。它代表着垃圾收集并且指向一个依靠堆栈类型,并由运行时间控制的对象。_box关键字可以解决我在上面提到的,如何将整数传给基本类库方法,它得到的是System::Object _gc而不是一个整数。下面是它的使用方法:
|