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
常量指针和指正常量有区别?我的之前的博客里面提到过:https://blog.csdn.net/m0_37690319/article/details/79607836,如果有兴趣可以看一看,很多人说了方法const在*左边表示被指物是常量,如果在const在*右边表示指针是常量,指针的指向是不能改的,举个例子:const char *p=greeting ,别指物是常量,有人会问那就是greeting是常量,那为什么我直接greeting[0]='w';没有出错
char greeting []="hello";
char *p=greeting;
p[0]='w'; //error
greeting[0]='w'; //正确
关于const的下面两种方式都是可以的,是一个意思,但是要注意啊,const *char,我本人也从来没见过,同时也是一种错误的写法,但是char * const 是有的。参考上面
const char *p=greeting;
char const *p=greeting;
补充一个迭代器的知识点,迭代器是按照指针的模型建造出来的,我们如果要一个迭代器的指向不能改,但是指向的东西是能改的,或者迭代器指向的东西不能更改,
std::vector<int> vec;
const std::vector<int> ::iterator iter=vec.begin();
std::vector<int> :: const_iterator citer=vec.begin();
const 成员函数
const成员你函数就是不允许修改改成员变量的值,const对象只能调用const成员函数,所以可以看看下面的类。
class TextBlock
{
public:
const char & operator[](std::size_t position) const //前面的额const char & 表示返回一个常量的引用,后面的const表示是const成员函数
{ return text[position]; }
char & operator [](std::size_t position)
{ return text[position];}
pricate
std::string text;
};
//调用情况,类中的构造函数省略,
TextBlock tb("hello");
std::cout<<tb[0]; //调用非const
const TextBlock ctb("world");
std::cout<<ctb[0]; //const对象只能调用const成员函数
tb[0]='x'; //注意这里是对返回的引用改变
ctb[x]='x'; //错误,不能对const 对象改变
注意一个问题:函数的返回值是内置类型,那么改动函数的返回值是不合法的,因为他返回的是右值,char & 如果换成 char,那么tb[0]='x'; 在这句话相当于在对char operator [](std::size_t position)这个函数的返回值进行赋值。
现在问一个问题,const成员函数就一定不更改对象的内容吗?看看下面的例子
class TextBlock
{
public:
char & operator[](std::size_t position) const
{ return text[position]; }
pricate
char * ptext;
};
const CTextBlock cctb("hello");
char *pc=&cctb[0];
*pc='j';
最终打印出来的是”jello“,有点超乎我们的想象,所以有时候const成员函数可以间接的修改内部对象的某些bit ,当然还可以使用另外的一种方法来修改,将成员对象声明为 mutable。
再问一个问题?为什么类的设计里面 同一个操作符要设置const版本和非const版本?因为const对象只能调用const成员函数,那我们可能会碰到这样的情况,
class TextBlock
{
public:
cosnt char & operator [](std::size_t position) const
{
...//边界校验
...//日志访问
...//检验数据的完整性
return text[position];
}
char & operator[] (std::size_t position)
{
...//边界校验
...//日志访问
...//检验数据的完整性
return text[position];
}
private:
std::string text;
};
甚至有人会问,何有什么问题吗?。。。。的确没什么问题,但是代码有些冗余,你也可以回答不就赋值粘贴一下吗,不麻烦。。。。。代码的重复面临着编译的时间,代码维护、代码膨胀,那么看看下面的方法
class TextBlock
{
public:
cosnt char & operator [](std::size_t position) const
{
...//边界校验
...//日志访问
...//检验数据的完整性
return text[position];
}
char & operator[] (std::size_t position)
{
const_cast<char &> (static_cast<const TextBlock &>(*this)[position]);
}
private:
std::string text;
};
将*this转换为 const去调用operator[]的const版本,const版本的返回值是 const char &,然后调用const _cast去掉const属性,这样就减少了代码的冗余,但是不要尝试这个方法的反响做法,在const版本里面去调用非const版本,这会产生不安全