当前位置导航:炫浪网>>网络学院>>编程开发>>C++教程>>C++进阶与实例

轻轻松松from C to C++ (二)

    二、挑战#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;
    }

 

 

共2页 首页 上一页 1 2 下一页 尾页 跳转到
相关内容
赞助商链接