荔园在线

荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀

[回到开始] [上一篇][下一篇]


发信人: sephiroth (Dreams Come True), 信区: Program
标  题: C++:与const有关的三个函数[转载]
发信站: 荔园晨风BBS站 (Fri Jan  3 21:47:45 2003), 站内信件


你也许有常量的概念并会用关键字const声明一个变量为常量,但是你知道const除
了声明常量外,还可以声明const指针和const成员函数。本文将讨论const对象是
如何建立、const对象的用途以及他们的语法。

Const声明

仅仅用一个关键字就可以声明三种截然不同的结构,所以const声明常常让人混淆
。让我们仔细看看这些这三种不同的const结构。

Const对象
当你把某个对象定义为const类型(在这里“对象”一词用的是它的广义语义,例
如保存一个变量或者类对象的一段内存)之前,你需要确保程序不会再修改它。
Const声明必须包括合适的初始化。代码清单A中包含有不同const对象的实例。

Listing A
const int MAX_FILES=15;
 const std::string ip_address=“202.180.109.89”;
 const char message[14]=“please rewind”;
 const double inch2cm = 2.54;

Const指针
如果把一个指针定义为const类型,那么程序就不能再让它指向一个新的地址。不
过const指针所指向的对象仍可以修改,如代码清单B所示。

Listing B


int n=10, m=0;
 int *const pci = &n; // pci is a const pointer to int pci++; // error,
 trying to modify a const pointer pci= &m; // also an error *pci=9; //OK




Const成员函数
一个类对象的状态由它的非静态数据成员组成。类中不需要修改对象状态的成员函
数应该定义为const类型。你可以在类的成员函数的参数表后面加上关键字const来
声明它为const函数。例如:

class Person{public:
     int getAge() const {return age;} //const成员函数
    private: int age;};

注意const成员函数是约束语法设计(the Design by Contract idiom)的一个重
要的组成部分。Const成员函数确保了编程者承诺要实现的功能(如,保持对象的
状态不变)由编译器强制实现。任何试图从内部修改const成员的举动都会导致编
译时错误的产生:


  int Person::getAge() const{
     return ++age; //编译时出错
    }
另外,const声明可以证明函数的行为。

混合类型

到目前为止,一切似乎都没有问题。然而,声明混合类型时麻烦不期而至。你能在
下面的例子中分辨出x和y是哪一种类型么?


const char * x= “hello”;
char const * y= “world”;

x和y的类型是一样的,即“指向const类型字符串的执政”——虽然const出现在x
和y的位置上。关键字const可以出现在它声明的变量的名字的前面或者后面,这不
会影响到声明的意义——这与下面例子中的关键字long和unsigned很相似:



    int long x;
    long int y;
    unsigned long l;
    long unsigned m;

现在,让我们看看下面这个const声明:

    char * const z= “world”;

这里,z的类型是“指向非const类型字符串的const型指针”。编译器是如何知道
变量z是const指针而x和y不是呢?


------------------------------------------------------------------------
--------
const指针和指向const变量的指针的区别是什么?
通过检查关键字出现在const星号之前还是之后,你可以区分const指针和const变
量。“* const”声明一个const指针,与之相反,当const出现在星号之前,指针
指向的对象是const类型的。
------------------------------------------------------------------------
--------

指向const对象的const指针
你可以在单个声明中把const对象和const指针联在一起,即声明指向const对象的
const指针。例如:


     const int n=10;
    const int * const p= & n; // 指向const int对象的const指针

因为p的声明中出现了“* const”,所以p是const型指针。p指向一个const型的整
数,因在它的声明中,关键字const出现在星号之前。在通过有固定地址的内存缓
冲来访问ROM设备的情况下,指向const对象的const指针的用法就特别有用。

现在,你也许正在想“我是不是可以在单个的声明语句中把三种const结构联在一
起?”,答案是肯定的。在下面的例子中,我们定义一个返回一个指向const整数
的const指针的const成员函数:



    class A{
    //…
    const int * const get_scores(int id) const;
    };

运算符const_cast<>
const_cast<>运算符用来消除对象的const属性。不过,使用这个运算符还有几个
限制,我们将简单的讨论这些限制。

消除const属性
尽管const_cast<>可以消除一个对象的const属性,但这并不意味着你就可以修改
该对象。考虑下面的例子:

     const char * p= “hello world”;int main() {
     char * s = const_cast <char *> (p); // 消除const属性
     strcpy(s, “danger!”); // 不可以,不明确的状态
    }

试图重写字符串s将会导致不明确的状态。其原因是const对象可能保存在系统的只
读内存中。如果你强制去除一个对象的const属性可以把该对象当着非const对象使
用(例如,把它传递给一个接受char *类型参数的函数),但不能修改它。

非const型到const型的转换
绝大多数程序员不知道const_cast<>也有相反的操作,也就是说,它可以把一个非
const型的对象转换为const型对象。例如:


    char s[]= “fasten your seatbelt”;
    size=strlen(const_cast<const char *> (s));// 更明确

但是你可以看到使用const_cast<>h的机会很少,原因是C++在需要使用const型对
象的环境下会自动执行非const型到const型的转换。因此,你不会真正需要这样使
用const_cast<>,除非你想验证你的代码。

结论
const在语法上的障碍常常使得编程者放弃使用它,这就削弱了编程质量和产生的
代码的可读性以及可维护性。诚然,指向const对象的指针和const指针的区分不应
该这么容易混淆——尤其是在处理混合类型时;不过,通过检查const限定词相对
星号的位置可以消除上述的模糊性,并且,const成员函数很容易辨识(const出现
在参数表后)。如果你对const感到头痛的话,相信通过本文,你会发现const的妙
用。
--

一直以来我都在找一个喜欢她的理由,因为我不相信在怎么短的时间内我居然爱的
如此深。可是 有一天我突然发现我根本就找不到理由,我随着 宿命漂着,直到我
陷的无法自拔,我才知道我对她的爱根本就不能限定在一个理由。那个飘零,我把
他当成了宿命,我爱她

※ 来源:·荔园晨风BBS站 bbs.szu.edu.cn·[FROM: 192.168.44.81]


[回到开始] [上一篇][下一篇]

荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店