zoukankan      html  css  js  c++  java
  • effective c++(03)之const使用方法

    char greeting[] = "hello";
    char* p = greeting;                       //non-const pointer,non-const data
    const char* p = greeting;              //non-const pointer, const data
    char* const p = greeting;              //const pointer,non-const data
    const char* const p = greeting;     //const pointer, const data

    以上为const面对指针时所产生的四种情况。

     const 如出现在星号左边,表示被指物是常量;如果出现在星号右边,表示指针本身是常量;如果出现在星号两边,表示被指物和指针都是常量。

    如果被指物是常量,const写在类型之前和类型之后都可以,意义相同,一下两种写法相同:

    void f1( const type* pw );
    void f2( type const* pw );

    而对于STL迭代器。所有的迭代器作用就跟T*一样。声明迭代器为const就像声明一个const指针一样,表明迭代器不能指向不同的东西。如果想让迭代器指向的东西不可改变,则需要声明const_iterator。如下:

    const vector<int>::iterator iter = vec.begin();     //如 T* const
    *iter = 10;                                                        //没有问题
    iter++;                                                             //不可执行
    
    vector<int>::const_iterator citer = vec.begin();   //如 const T*
    *citer = 10;                                                       //不可执行
    citer++;                                                            //可以


     

    const最具有威力的用法是面对函数声明时的应用:

    class Rational {...};
    const Rational operator* ( const Rational& lhs, const Rational& rhs);
    
    Rational a,b,c;
    ...
    (a*b)=c;

    如以上例子,对两个数值的乘积做了一次赋值,将operator*的回传声明为const可以预防这种没有意思的动作。

    const成员函数

    如果函数的返回类型是内置类型,那么如果改动函数返回值从来就不合法。如果返回类型为引用,则可以给返回值赋值。

    class TextBlock{
    public:
        const char& operator[]( size_t position ) const
        {
            return text[position];
        }
        char& operator[](size_t position)
        {
            return text[position];
        }
    private:
        string text;
    };

    如上类中,如果有以下调用:

    TextBlock tb("hello");
    cout << tb[0];
    const TextBlock ctb("world");
    cout << ctb[0];

    tb直接调用类中的non-const成员函数,ctb调用的是const成员函数,如下代码:

    cout << tb[0];
    tb[0] = 'x';
    cout << ctb[0];
    ctb[0] = 'x';

    ctb[0]='x'是不可以被执行的,因为const成员函数返回的是const的引用,并且const成员函数所使用的数据成员不可以被更改。

    但是由于以上的方法却产生了以下问题:

    class CTextBlock{
    public:
        char& operator[]( size_t position ) const
        {
            return pText[position];
        }
    private:
        char* pText;
    };

    对于以上的类在如下调用时:

    const CTextBlock cctb("hello");
    char* pc = &cctb[0];
    *pc = 'J';

    此时cctb为‘Jello’。
    以上为 bitwise const 的观点,虽然const成员对象没有改变类的数据成员,但是整体上是改变了,这样的情况下const类成员意义不大,终究还是改变了其值。

    于是产生了logical constness的观点:

    class CTextBlock{
    public:
        size_t length() const;
    private:
        char* pText;
        size_t textLength;
        bool lengthIsValid;
    };
    size_t CTextBlock::length() const
    {
        textLength = strlen(pText);
        lengthIsValid = true;
        return textLength;
    }

    以上代码显然没法执行,因为在length为const成员函数不能改变数据成员。logical constness的观点如下:

    class CTextBlock{
    public:
        size_t length() const;
    private:
        char* pText;
        mutable size_t textLength;
        mutable bool lengthIsValid;
    };
    size_t CTextBlock::length() const
    {
        textLength = strlen(pText);
        lengthIsValid = true;
        return textLength;
    }

    在const成员函数前加上mutable即可实现const成员函数改变数据成员。

  • 相关阅读:
    再理解HDFS的存储机制
    C实现头插法和尾插法来构建单链表(不带头结点)
    linux系统编程:线程同步-相互排斥量(mutex)
    基于github for windows&amp;github的团队协作基本操作
    分治法求众数问题 (配图)
    hdu1576 mod 运算的逆元
    Android5.0(lollipop)新特性介绍(一)
    jenkins详解(一)
    手机APP测试点总结
    App测试方法总结
  • 原文地址:https://www.cnblogs.com/2011winseu/p/3180570.html
Copyright © 2011-2022 走看看