C++中const的使用和放在函数前和函数后的区别

C++中const的使用和放在函数前和函数后的区别

(1) 如果关键字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 
(2) STL迭代器系以指针为根据塑模出来,所以迭代器的作用就像个T*指针。声明迭代器为const就像声明指针为const一样(即声明一个T* const 指针),表示这个迭代器不得指向不同的东西,但它所指的东西的值是可以改动的。如果希望迭代器所指的东西不可被改动(即希望STL模拟一个const T* 指针),你需要的是const_iterator:
vector<int>vec;
const vector<int>::iterator iter = vec.begin();  //iter的作用像个T* const
*iter =10;                                      //没问题,改变iter所指物
++iter;                                        // 错误,iter是const
vector<int>:: const_iterator cIter = vec.begin();  //cIter的作用像个const T*
*cIter =10;                                     //错误,*cIter是const
++cIter;                                       //没问题,改变cIter
(3)const成员函数
#include <iostream>
using namespace  std;
class TestClass {
public:
    size_t length() const
    {
        if(!lengthIsValid)
        {
             contentLength= strlen(pContent);    //C
             lengthIsValid = true;           //D
        }
        return  contentLength;
    }
    const char* getPContent()
    {
        return  pContent;
    }
    void setLengthValid(bool isLengthValid)
    {
        lengthIsValid = isLengthValid;
    }
private:
    char* pContent =nullptr;
    size_t  contentLength;       //A
    bool  lengthIsValid;         //B
};

int main(void){
    TestClass *tc =new  TestClass;
    tc->setLengthValid(false);
    tc->length();
    const char* content = tc->getPContent();      //E
    return  0;
}
里面有三个错误,也就是代码C、D、E处的三个地方。为什么C和D处的代码会出错,原因如下:

length函数名的后面加了const修饰符,这样说明成员变量(static除外)是不允许修改的。我们都知道,在类的成员函数里面,默认是在成员函数的第一个位置是this指针,如果在成员函数(只能是成员函数,要是类的静态函数或者是非成员函数就不可以在函数名后面加上const)后面const,则说明this指针的值是不可以修改的,只能读取。而上面的length函数可能会修改里面的contentLength和lengthIsValid的值,这样编译器肯定是不允许的,所以这样是会出现错误的。解决方法是:在类的A、B处的成员前面加上mutable修饰符:

 mutable  size_t  contentLength;   //A
 mutable  bool  lengthIsValid;     //B

从字面的意思知道,mutalbe是“可变的,易变的”,跟constant(既C++中的const)是反义词。在C++中,mutable也是为了突破const的限制而设置的。被mutable修饰的变量,将永远处于可变的状态,即使在一个const函数中。这样在C、D处将不会出错。

那么,为什么E处出现了错误。这是因为在函数名getPContent前加了const修饰符,意味着该函数返回的值只能是读取,而不能被修改。而E处的content却为char*是可以被修改的,这与const正好相反了,所以出现了错误。解决方法是:在char* 前面加上const修饰符,即:

const  char* content = tc->getPContent(); //E
(4) const放在成员函数后有些情况可以改变
#include <iostream>
using namespace std;
class CTextBlock
{
public:
    CTextBlock(const string& text)
    {
        pText =const_cast<char*>(text.c_str());
    }
    ~CTextBlock()
    {
        pText = nullptr;
    }
    char& operator[](size_t position) const
    {
        return pText[position];
    }
    void outPut() const
    {
        cout << pText <<endl;
    }
private:
    char *pText=nullptr;


};
int main()
{
    const CTextBlock cctb("Hello");
    char* pc = &cctb[0];
    pc[0] ='J';
    cctb.outPut();
    return 0;
}
在这种情况不会引发编译器异议,bitwise const阵营的人相信,成员函数只有在不更改对象之任何成员变量(static除外)时才可以说是const。也就是说它不更改对象内的任何一个bit。这种论点的好处是很容易侦测违反点:编译器只需寻找成员变量的赋值动作即可。
  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ThomasKUI

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值