情有独钟C++:Visual C++ .NET编译器的新特性(转)[@more@]
摘要
老资格的 C++ 程序员们都想知道:他们赖以生存的 C++ 语言在 C# 和微软的 .NET 的冲击下何去何从?本文将对 .NET 世界中的 C++ 进行简要描述。在 .NET 中,C++ 分裂为两大阵营:受管代码 (Managed Code) 和非受管代码 (Unmanaged Code)。非受管代码不使用通用语言运行时环境 (CLR) ,而受管代码则用到了 Managed Extensions for C++ 。本文将对两者分别讨论。
C++ 社区给人的感觉就象一个大家庭:初生的小宝宝总是倍受呵护,而年长的孩子却是无人关心。如此被忽视,又怎能教人不心痛?事实上,技术领域的情况比这更糟:技术的革新实在太快,人们疲于奔命却无可奈何,否则连饭碗都保不住了。
如今,微软公司的新产品 .NET 框架被炒得沸沸扬扬——的确很不错;众人还对所谓的 C# 语言连声喝彩。作为 C++ 的程序员,心里却很不是滋味:我是不是也要改行学 C# 了?因为人们只有在比较 C# 与 C++ 才会偶尔提及 C++ 了。
C++ 程序员要过时了吗?绝不!本文先简要描述 Visual Studio .NET 为 C++ 引入的新特性,然后再介绍微软公司对新版 C++ 的计划。首先从两个方面来谈谈 Visual Studio .NET 里的 C++ :标准的 C++ 和 Managed Extensions for C++ 。
对标准 C++ 的扩充主要是为了保持兼容性;也就是说,为了保持国际标准化组织 (ISO) 所规定的 C++ 语言特性。而 Managed Extensions for C++ 则是为了把 C++ 纳入 .NET 框架之中。
Visual Studio .NET 下的标准 C++
为了保持对 ISO 标准的兼容性,标准 C++ 作了如下改进:
(1) 虚拟函数的返回值现在支持共变 (covariant) 类型了,这是类层次体系上的一个重大改进;
(2) 支持对静态整数类型常量( static const integer )成员的显式初始化;
(3) 主函数的返回值默认为 0 。
现在我来逐一介绍它们。
第一项是增加 covariant 返回类型,它已经由标准委员会核准。也就是说,如果基类的某个虚拟函数返回值是该类本身的实例,那么它在派生类中被重载后也能返回此派生类本身的实例。在类层次体系中,这是一种很重要的设计模式;在 Visual Studio .NET 中,它也大受欢迎。
例如,对于抽象基类 Query :
class Query {
public:
virtual Query *clone() = 0;
// ...
};
如果想要其派生类实例 NotQuery 的 clone 函数返回一个 NotQuery 对象,即:
class NotQuery {
public:
virtual Query *clone()
{ return new NotQuery( this ); }
// ...
public:
Query *operand;
};
当没有 covariant 返回类型支持时,clone 的返回类型必然是 Query* :
// without covariant return type support
virtual Query* clone()
{ return new NotQuery(
this ); }
此时如果把 clone 的返回值分配给 Query* 类型的指针,那么一切工作正常:
NotQuery::NotQuery( const NotQuery &rhs )
{ operand = rhs.operand->clone(); }
但是如果要分配给 NotQuery* 类型的指针呢?
NotQuery nq( new NameQuery( "Shakespeare" );
这样就不行了:
// oops: illegal assignment ...
NotQuery *pnq0 = nq->clone();
只能这样:
// ok: required explicit cast ...
NotQuery *pnq1 =
static_cast
(nq->clone());现在有了 covariant 返回类型,你就可以显式返回 NotQuery* 类型了:// with covariant return type supportvirtual NotQuery* clone(){ return new NotQuery( this ); }于是,clone 的返回类型变得更直观,不再需要强制类型转换了:这样是对的:// ok: implicit conversion ... ;Query *pq = nq->clone();这样也没问题:// ok: no conversion necessary ... ;NotQuery *pnq = nq->clone();第二项是静态整数常量类型成员的显式初始化,它对 C++ 的影响就没有 covariant 返回类型那么大了。它仅仅给使用常量表达式(如:定长数组)的类的设计带来了方便。例如:class Buffer {static const int ms_buf_size = 1024;char m_buffer[ ms_buf_size ];};static const int 类型成员被初始化以后,就可以为本类的其它成员所用,例如设置 m_buffer 的大小,而不用象以前那样,使用枚举变量了。第三项是主函数的默认返回值为 0 。主函数的返回值代表程序的退出状态。习惯上,返回 0 代表程序正常结束。在标准 C++ 里,如果没有显性指定返回值,编译器就会自动地在主函数末尾插入一行:return 0;进入 Visual Studio .NET 时代,Visual C++ 终于支持它了!Visual Studio .NET 下的受管 C++ Visual Studio .NET 的 Managed Extensions for C++ 提供了三种基本的应用策略:(1) 为原有的 API 提供 .NET“包装”,把 C++ 类统统移植到 .NET 平台中。(2) 混用 C++ 类与微软 .NET 的三种框架类:核心语言支持,例如:收集类和系统输入/输出;基础程序类, 例如:线程支持,网络套接字和正规表达式;应用领域支持,例如:XML、ASP.NET、Web 服务、Windows 窗体、ADO.NET,等等。(3) 象 C# 和 Visual Basic 那样直接操作 .NET 环境。然而,目前尚无相应的快速开发工具(RAD)用于 Windows 窗体和 Web 表单的可视化编程。先来看看第一种方案:用 .NET 包装原有的代码。在我的 C++ Primer 一书 (Addison-Wesley,1998) 中,我示范了一个相当大的文本查询系统,其中大量使用了 STL 容器类用于解析文本文件和建立数据结构。它的引用文件内容如下:#include #include #include #include #include
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/8225414/viewspace-946142/
,如需转载,请注明出处,否则将追究法律责任。