今日更新
技术新闻
精彩专题
IBM软件技术专区
微软开发专区
技术文档中心
编程语言
网络通信
网络安全
LINUX/UNIX
软件工程与管理
数据库开发
WEB开发
企业应用与开发
移动开发
资源中心
原创专栏
开放系统世界
人才与培训
技术天地论坛
厂商列表
社区推荐

· 女性身体内部人体受孕..
· 十部顶级的变态与情色..
· 感情放纵让我毁了两个..
· 当我撞见姐姐和男友在..
· 卖淫少女惨遭泄愤民工..
· 偷拍街上的走光mm绝对..
· 百度打击google的广告
· 港娱乐圈与黑社会揭秘
赛迪网>>技术应用>>上首页
关键字: C , C++
来  源: vcer.net
轻轻松松C to C++ (二)
作者:vcer 发文时间:2004.08.24
接上一篇

二、挑战#define

#define是C提供的一条很有用的指令,但在C++中,很有可能杜绝宏指令的使用。

1 .const

宏指令允许用户指定某一标识符的值作为一个常量,如:
#define PI 3. 1415926

它也可以用来定义字符串:
#define HZK16 "HZK16F"

以下使用可以通过:

cout << "PI is“<<PI;
cout << "Filename: "<< HZK16;


但宏毕竟不是一个合法的对象,虽然它伪装得很完美。C++为用户提供了常量修饰符const,可以指定某个对象的值为常量。它阻止用户对其进行赋值或其它副作用,类似于上例:

const float PI=3.1415926;
char*const HZK16="HZK16F";
PI = 3. 14; //error
HZK16="HZK16K"; //error: Cannot modify a const object


但对于指针的处理似乎有些复杂,例如以下使用却又合法:
HZK16[5]=’r’; //ok HZK16 ="HZK16K"

清楚地了解const修饰的范围很有必要,如下是声明形式与相应含义:
char*const cpl="I love you!“; //const修饰’*’,cp1是一个指向字符的指针常量
const char*cp2="I hate you!“; //const修饰’char' cp2是一个指向字符常量的指针
const char*const cp3="Get the hell out of here!“; // const分别修饰’char’和’*’,cp3是一个指向字符常量的指针常量

因此,以下使用仍合法:
strcpy(cpl "Oh no...“);
cp2++;

因为cpl只管盯住某一处的地址不放,而阻止其中的内容不被改写则不是它的责任,cp2则恰恰相反,它不允许你修改其中的内容,却可以被你指来指去(这个下场可能更惨)。只有使用两个修饰符(如cp3)才可能是最保险的办法。

指向const的指针不能被赋给指向非const的指针:
float*p=&PI;
//error: Cannot convert 'const float*’ to 'float*’
*p=3.14;

这条限制保证了常量的正当含义。但注意由显式转换所引起的常量间接修改是可能的:

//test08.cpp
#include <iostream.h>
void main()
{
       char * Spy;
       const char * const String = "Yahoo!";
       Spy = (char*)String;
       Spy[5] = '?';
       cout << String;
}
 
Yahoo!


**作者按:以上程序在Visual C++下运行会报内存错误。

2.内联函数(in line function)

宏在某些场合能得到类似于函数的功能,如下是一个常见的例子:
#define ADD (a b) ((a)+(b))
cout<<”1+2=”<
它将实现数据求和功能而输出:

但我们至少有一打理由拒绝使用它,以下是最明显的:

①宏缺少类型安全检测,如:
ADD ('A' 0. 0l);
这样的调用将被解释为合法,而事实上,很少的用户期望能写出这样的语句;

②宏不会为参数引入临时拷贝,如:

#define DOUBLE (x)((x)+(x))
int i(1);
cout<<DOUBLE(i++); //prints '3'


③宏不具有地址,例如可能在一个计算器程序中有:
case ' +': Operator = & ADD;
并不能得到合理解释。

采取函数?然而,使用函数并不是最划算的支出,它浪费了宝贵的执行时间。使用过汇编语言的读者可能知道,一般函数执行真正的函数体前后,要做一些现场保护工作,当函数体积很小时,这种冗余的工作量将会远远大于函数本身。

为此,C++提供了关键字inline,当用户希望编译器将某函数的代码直接插入到调用点时,可将其设置成inline函数,即在函数定义时加上关键字inline,如:

//test09.cpp
#include <iostream.h>
inline int Add (int a int b)
{
return a + b;
}
void main O)
{
cout<<"1+2=“<<Add(1 2);
}


主函数将被编译器解释为:
count<<"1+2=”<<{1+2 };

其行为完全类似于前例的ADD (a b)宏。经验表明,将使用频繁而且体积很小的函数声明为inline是明智的。

3.函数重载(overload)

在实际数据求和操作时,如上节内容中提供的Add()函数是远远不够的,你不得不再添加一些其它代码,如:

double AddDouble(double a double b)
{
return a + b;
}
float AddFloat (float a float b )
{
return a + b;
}


特别地,在C++中你可以玩弄名字的技巧,将以上的AddDouble AddFloat皆取名为Add,如:

double Add(double a double b)
{
return a + b;
}


尽管放心,编译器会安全地为不同的调用形式找到相应的函数原型。如:

double a b;
Add(f 2); //int Add(int int)
Add (a b); //double Add (doubledouble)


这样,不同的函数拥有相同的函数名,即函数重载。函数重载以及后面的模板、虚函数机制形成了“一个接口,多种功能”的特性,即多态性(polymorphism),它是面向对象(OO)的技术之一。

在使用重载机制时,C++提出了许多防止二义性的限制,如:

void fun(int a);
int fun(int a);
void fun(int& a);
void fun (int a int b=0);


很可能引起C ++编译器的恐慌,它在遇到诸如fun(100)的调用时会十分不满。用户有义务保证任一调用形式不产生二义性。以下是一种常见的使用重载机制的例程:

//test10.cpp
#include <graphics.h>
#include <iostream.h>
void Pixel(int x int y int color)
{
       putpixel(x y color);
}
 
int Pixel(int x int y)
{
       return getpixel(x y);
}
 
void main()
{
       int Driver=VGA Mode=VGAHI;
       initgraph(&Driver &Mode "");
       Pixel(100 100 4);
       int Color = Pixel(100 100);
       closegraph();
       cout << "Color of point(100 100):" << Color;
}


可以想象C++将以上不同的Pixel()函数分别编码为Pixel_iii和Pixel_ii,它的形式包含了各入口参数的数据类型。注意,编码未包含返回值的信息,因而依赖于返回值类型的差异的函数重载是不稳定的。因此,连接器(linker)可以毫不费力地找到相应的模块。但这对于新旧C版本产生的模块连接恐怕添加了麻烦,因为传统的C函数库中并没有对函数名再作手脚的坏习惯,C++不得不提供关键字extern来保证这种连接的安全性,如下形式(注意’C’可要大写):

extern "C"
{
void Pixel(int x int y int Color);
};


将告诉编译器只需要在函数库中找相应的Pixel模块,而不必自作聪明。而

extern "C"
{ //' #include’一定要另起一行
#include "function. h"
};


则声明包含在头文件function. h中所有函数模块皆采取C连接。

T111




赛迪网推出“IT博客”,花不到一分钟就完成注册
评论】 【推荐】 【 】 【打印】 【关闭

·Linux专区· ·黑客攻防·
· Linux下添加硬盘、分区、格式化任务详解
· FreeBSD服务器的安装与优化之优化篇
· 初学者入门:FreeBSD服务器的安装与优化
· 金企鹅杯两岸四地开源软件大赛圆满结束
· 如何提高Linux系统安全性的十大招数
· 构筑Linux防火墙之为个人用户设置防火墙
· 谁更安全?黑客眼中的防火墙与路由器
· 识破骗局 练就识别QQ活动真伪火眼金睛
· 应用安全大有可为:目的、挑战、总结
· 道高一尺魔高一丈:安全防御的动感魅力
· 警惕网络“内”院起火 积极谋求安内之路
· HHCTRL漏洞被黑客利用 疯狂传播木马
·中国信息化· ·成功案例·
· ERP普及化是饮鸩止渴 精细化才是应用之道
· 赛门铁克第八期《互联网安全威胁报告》解析
· 抢食“数字工商” 国产中间件杀出血路
· 从IBM等操作系统的发展看软件创新的启示
· 服务成就蓝色快车 品牌是怎样炼成的?
· 三大技术应用大会合为一体甲骨文上演三重奏
· 南阳教育城域网 拆掉学校间的“围墙”
· 金算盘助申意美步入信息化快车道
· 不为人知的索尼信息化 谁是幕后英雄?
· InforBus/Q在穗高速路联网收费系统中的应用
· J2EE构建最新金融理念和运作模式的网上银行
· 食品安全令人担心 信息化能否保驾护航
*姓  名: 更多资料 了解方案 认识厂商
*单位名称:
*联系电话:
*电子邮件:
    
◆ 相关文章   ◆ 站内热点推荐
· 网管员论坛
· 开发者之家
· WLAN无限未来
· 我是如何掉进C#的……
· 中国“人件”非正式调查

   
合作网站: IBM dW中国网站 LinuxAID 软件工程专家网 中国系统分析员 UMLChina MATRIX Mobile2008 JavaResearch 华储网 UML软件工程组织 中国JAVA手机网 JAVA中文站 金山在线 海量科技