科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件在可管理C++中封装值类型 (1)

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

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

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

作者:李阳编译 来源:赛迪网 2007年11月16日

关键字: 封装值类型 C++ Linux

  • 评论
  • 分享微博
  • 分享邮件

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

查看本文来源
    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章