Answers:
(1)const的使用场合有哪些?
(2)const的规则?
(3)const函数?
(4)const STL迭代器?
(5)const函数重载?
--------------------------------------------------------------------------------------------->
Questions:
(1)const的使用场合有哪些?
a.在class外部修饰global或者namespace(reference Item2)作用域中的常量
const int MAXNUM = 100;
b.在class内部修饰static和non-static成员变量
class MyTest
{
private:
static const int MaxNumber = 5;
const int MinNumber = 1;
int score[MaxNumber];
};
c.在文件、函数、区块作用域(block scope)中修饰被声明为static的对象
const MyTest myTest;
d.对于指针,可以修饰指针本省、指针所指物、或者同时修饰两者
int a = 100;
const int* p = &a;
int* const p = &a;
const int* const p = &a;
e.修饰函数返回值,函数参数,成员函数本身(非成员函数不能使用const修饰本身)
const char& operator[](std::size_t position);
const char& operator[](std::size_t position) const;(必须是成员函数)
char& operator[](const std::size_t &position)
(2)const的规则?
a.如果const出现在*左边,表示被指物是常量
b.如果const出现在*右边,表示指针本省是常量
c.如果const出现在*两边,表示被指物和指针本身都是常量
d.如果const出现在函数参数表括号后面,表示不会修改该类的数据成员
e.如果const出现在函数开头,表示函数的返回值为常量,接收该函数返回值的变量值不允许修改
(3)const函数?
const函数的声明和定义都必须使用关键字const。在声明const函数时,关键字const插在函数参数列表之后;在定义const函数时,关键字const必须插在表示函数体开始的左花括号之前。
任何不会修改数据成员的函数都应该声明为const类型。如果在编写const成员函数时,不慎修改了数据成员,或者调用了其它非const成员函数,编译器将指出错误,这无疑会提高程序的健壮性。
以下程序中,类stack的成员函数GetCount仅用于计数,从逻辑上讲GetCount应当为const函数。编译器将指出GetCount函数中的错误。
class Stack
{
public:
void Push(int elem);
int Pop(void);
int GetCount(void) const; //const成员函数
private:
int m_num;
int m_data[100];
};
int Stack::GetCount(void) const
{
++m_num; //编译错误,企图修改数据成员m_num
Pop(); //编译错误,企图调用非const函数
return m_num;
}
const函数可以修改声明为mutable的数据成员:
#include <iostream>
#include <string>
using namespace std;
class TextBlock
{
private:
std::string text;
mutable std::size_t textLength;
public:
TextBlock(): text(""){}
TextBlock(const char t[]): text(t){}
TextBlock(const TextBlock& tb): text(tb.text){}
const char& operator[](std::size_t position) const // const function
{
//text = "hello"; //error:can't modify the data member in const function
cout<<"call const char& operator[]: ";
return text[position];
}
char& operator[](std::size_t position)
{
cout<<"call char& operator[]: ";
return text[position];
}
std::size_t length() const // const function
{
textLength = text.length(); //ok
return textLength;
}
~TextBlock(){}
};
(4)const STL迭代器?
STL迭代器的作用像T*指针
声明迭代器为const就像声明指针为const一样,即声明一个T* const指针,表明迭代器不能指向不同的东西,但所指的东西的值可变;
若希望迭代器所指的东西不可改变,即希望STL模拟一个const T*指针,则需要const_iterator;
如:
std::vector<int> vec;
...
const std::vector<int>::iterator iter = vec.begin(); //iter即T* const指针,指针本身不可变
*iter = 10; //ok
++iter; //error, because iter is const
Std::vector<int>::const_iterator citer = vec.begin(); //citer即const T*指针,指针所指物不可变
*citer = 10; //error, because *citer is const
++citer; //ok
(5)const函数重载?
两个成员函数如果只是常量性(constness)不同,可以被重载。
#include <iostream>
#include <string>
using namespace std;
class TextBlock
{
private:
std::string text;
public:
TextBlock(): text(""){}
TextBlock(const char t[]): text(t){}
TextBlock(const TextBlock& tb): text(tb.text){}
const char& operator[](std::size_t position) const // const function
{
//text = "hello"; //error:can't modify the data member in const function
cout<<"call const char& operator[]: ";
return text[position];
}
char& operator[](std::size_t position)
{
cout<<"call char& operator[]: ";
return text[position];
}
~TextBlock(){}
};
int main(int argc, char* argv[])
{
int a = 100;
const int* p = &a;
int* const p = &a;
TextBlock tb("Hello");
std::cout << tb[0]<< endl; //call non-const TextBlock::operator[]
const TextBlock ctb("World");
//ctb[0] = 'w'; //error:write to a const TextBlock
std::cout << ctb[0] << endl; //call const TextBlock::operator[]
return 0;
}