• 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成员函数改变数据成员。

  • 相关阅读:
    使用NPOI导入导出标准Excel
    winform ListView应用之分组、重绘图标、网格线
    在网页中显示CHM
    动态表单(javascript实现)
    批量上传文件时,js验证文件名不能相同
    IE开发人员工具无法使用
    卸载方法 gnu grub version 0.97
    VS.Net 2003/VC6.0常用快捷键集合
    SQL SERVER 与ACCESS、EXCEL的数据转换
    通用获取父节点/子节点/子节点下所有节点ID的存储过程
  • 原文地址:https://www.cnblogs.com/2011winseu/p/3180570.html
Copyright © 2020-2023  润新知