C++中的const
2013-05-03 20:53
288 查看
const告诉编译器它所约束的对象是不允许被修改的,它可以作用于任何作用域类的对象(包括类对象),函数参数和返回值,及成员函数本体,使用它可以在编译时及时发现错误。
1)const与指针
const可以修饰指针本身,也可以修饰指针所指的对象,或者限制指针与其所指对象都为const,如下:
注意,const限制指针所指物不可修改时,有以下两种方式:
也就是说,const既可以位于数据类型前也可以位于数据类型后,但必须位于星号前,它们组合在一起用来修饰指针所指的对象。可以这样理解,星号前面的用来修饰被指物,星号
后面的用来修饰指针。
2)const与STL迭代器
STL迭代器与指针类似(难道不是一样的吗?),用const修饰迭代器就像声明指针为const一样,表示该迭代器不能指向不同的东西,如果要限制迭代器所指的对象不可修改,则需
要使用const_iterator,具体如下:
3)const修饰函数参数及返回值
对于函数声明:
它表示函数的参数和返回值都是不可以被修改的,所以下面的代码就是错误的:
4)const与成员函数
a. 被const修饰的成员函数使得操作“const对象”成为可能,例如下面的代码编译就无法通过:
此时可以添加const成员函数来操作const对象:
b. 被const修饰的成员函数不改动任何非static成员变量,下面的情况除外:成员变量是一个指针类型,此时指针所指的地址不可以改变,但指针所指的对象却可以改变。比如将
上面代码中的成员变量pText改为char*类型,即声明如下:
同时令对应的const成员函数的返回值不再是const类型,具体修改如下:
那么下面const成员函数调用也是正确的:
这样的情况编译器能够通过是因为在const成员函数确实没有改变成员变量pText的值,只是改变了该值对应的变量。如果执意要在const成员函数中对成员变量进行赋值操作,那
么可以引入摆动场:mutable,它将释放在const成员函数中非static成员变量的不可改动性。
例如如下代码将通过编译:
5)const转型
如果两个重载函数只是在是否是常量性上有区别,要做的事几乎一样,那么可以通过将常量性转除来实现调用两次却只执行一次的功能,这样一来就避免了代码的重复,从而减
少编译时间,代码维护时间以及避免代码膨胀等问题。因为const成员函数的本意是不修改对象,而non-const成员函数却可以对对象做任意的修改,所以在const成员函数中调用
non-const是不合理也是不允许的,但是在non-const成员函数中调用const成员函数却是可行的,具体如下:
上述代码中有两次转型操作,首先通过static_cast<const Head&>将类型为Head&的*this转为const Head&类型,从而调用const的成员函数,然后通过const_cast<char&>去掉const成员函数返回值的const属性。
切记:const成员函数不可以调用non-const成员函数。
1)const与指针
const可以修饰指针本身,也可以修饰指针所指的对象,或者限制指针与其所指对象都为const,如下:
const char* p = "hello";//non-const pointer, const data char* const p = "hello"; //const pointer, non-const data const char* const p = "hello"; //const pointer, const data
注意,const限制指针所指物不可修改时,有以下两种方式:
const char* p = "hello"; char const * p = "hello";
也就是说,const既可以位于数据类型前也可以位于数据类型后,但必须位于星号前,它们组合在一起用来修饰指针所指的对象。可以这样理解,星号前面的用来修饰被指物,星号
后面的用来修饰指针。
2)const与STL迭代器
STL迭代器与指针类似(难道不是一样的吗?),用const修饰迭代器就像声明指针为const一样,表示该迭代器不能指向不同的东西,如果要限制迭代器所指的对象不可修改,则需
要使用const_iterator,具体如下:
std::vector<int> v; ... const std::vector<int>::iterator<int> iter = v.begin(); // iter是不能更改的,类似T* const *iter++; //ok! iter++; //error, iter是const常量 std::vector<int>::const_iterator<int> iter = v.beign(); //iter不是const,所指对象是const,不能更改 *iter++; //error! iter++; //ok!
3)const修饰函数参数及返回值
对于函数声明:
const int operator*(const int& a, const int& b) { return a*b; }
它表示函数的参数和返回值都是不可以被修改的,所以下面的代码就是错误的:
int a = 3; int b = 4; int c = 5; a*b = c; //a*b返回的是一个const常量,不可以修改
4)const与成员函数
a. 被const修饰的成员函数使得操作“const对象”成为可能,例如下面的代码编译就无法通过:
class Head { public: Head(string s) { pText = s; } char& operator[](size_t pos) { return pText[pos]; } private: string pText; } int main() { const Head h1("Hello"); cout<<h1[1]<<endl; //成员函数operator[]不能操作const对象 }
此时可以添加const成员函数来操作const对象:
const char& operator[](std::size_t pos) const { return pText[pos]; }
b. 被const修饰的成员函数不改动任何非static成员变量,下面的情况除外:成员变量是一个指针类型,此时指针所指的地址不可以改变,但指针所指的对象却可以改变。比如将
上面代码中的成员变量pText改为char*类型,即声明如下:
char* pText;
同时令对应的const成员函数的返回值不再是const类型,具体修改如下:
char& operator[](std::size_t pos) const { return pText[pos]; }
那么下面const成员函数调用也是正确的:
const Head h2("Good"); char* p = &h2[0]; *p = 'J'; //此时pText所指向的字符串为“Jood”
这样的情况编译器能够通过是因为在const成员函数确实没有改变成员变量pText的值,只是改变了该值对应的变量。如果执意要在const成员函数中对成员变量进行赋值操作,那
么可以引入摆动场:mutable,它将释放在const成员函数中非static成员变量的不可改动性。
例如如下代码将通过编译:
class Head { public: ... size_t length() const; private: char* pText; mutable size_t textLength; //表示这些变量可能经常会被改动,即使在 mutable bool LengthIsValid; //const成员函数里也有可能被修改 }; size_t Head::length() { if(!LengthIsValid) { textLength = strlen(pText); LengthIsValid = true; } }
5)const转型
如果两个重载函数只是在是否是常量性上有区别,要做的事几乎一样,那么可以通过将常量性转除来实现调用两次却只执行一次的功能,这样一来就避免了代码的重复,从而减
少编译时间,代码维护时间以及避免代码膨胀等问题。因为const成员函数的本意是不修改对象,而non-const成员函数却可以对对象做任意的修改,所以在const成员函数中调用
non-const是不合理也是不允许的,但是在non-const成员函数中调用const成员函数却是可行的,具体如下:
class Head { public: ... const char& operator[](std::size_t pos) const { return pText[pos]; } char& operator[](std::size_t pos) { return const_cast<char&>(static_cast<const Head&>(*this)[pos]); } }
上述代码中有两次转型操作,首先通过static_cast<const Head&>将类型为Head&的*this转为const Head&类型,从而调用const的成员函数,然后通过const_cast<char&>去掉const成员函数返回值的const属性。
切记:const成员函数不可以调用non-const成员函数。
相关文章推荐
- effecitve c++之const
- C++ static const成员 初始化
- C++关键字const用法详解
- 腾讯面试题03.C++里面的const是怎么实现的?
- 你所不知道的const------C++
- C++的类型转换:static_cast、dynamic_cast、reinterpret_cast和const_cast
- C++中const用法总结
- C++ 常量类型 const 详解
- C++中const简介及用法
- C++标准转换运算符const_cast
- 小议C++中const的实现机制
- Why do people use enums in C++ as constants while they can use const?
- c++基础:新标准constexpr基本用法及其他注意点
- 【C++专题】static_cast, dynamic_cast, const_cast探讨
- CRL及C++/CLI中的const、 literal i、nitonly与 友元
- C++每日一练(const)
- C++之const
- c++专题: const(转自http://blog.csdn.net/foxbillcsdn/archive/2006/05/24/752310.aspx)
- 关于C++ const 的全面总结
- C++ 之 constexpr And shared_ptr