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成员函数改变数据成员。
原文链接: https://www.cnblogs.com/2011winseu/p/3180570.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/95118

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月10日 上午2:57
下一篇 2023年2月10日 上午2:57

相关推荐