常成员函数,是指由const修饰符修饰的成员函数,在常成员函数中不得修改类中的任何数据成员的值。常成员函数表示成员函数隐含传入的this指针为const指针,决定了在该成员函数中,任意修改它所在的类的成员的操作都是不允许的(因为隐含了对this指针的const引用),唯一的例外是对于mutable修饰的成员。
常成员函数示例
class CTest2
{
public:
int GetValue() const
{
return m_iValue;
}
int m_iValue;
};
常成员函数使用注意事项
1. 非成员函数或静态成员函数,不能用const修饰
2. 常成员函数中,唯一可以修改的成员变量是mutable修饰的成员变量
3. 当一个类的对象被声明为常对象,则不能通过该对象调用该类中的非const成员函数
4. 加了const的成员函数可以被非const对象和const对象调用,但不加const的成员函数只能被非const对象调用
常成员函数使用的注意事项的示例程序,如下
#include <iostream>
#include <string>
void PrintHello() const //编译报错,error C2270: 'PrintTitle': modifiers not allowed on nonmember functions
{
std::cout << "Hello World" << std::endl;
}
class CTest
{
public:
CTest()
: m_iValue(-1)
{
}
virtual ~CTest()
{
}
void ValueAdd1() const //编译报错,error C3490: 'm_iValue' cannot be modified because it is being accessed through a const object
{
m_iValue = m_iValue + 1;
m_strValue = "test"; //该处不会编译报错,是因为m_strValue声明是在前面加了mutable
}
void PrintValue() const
{
std::cout << m_iValue << std::endl;
}
void PrintHi()
{
std::cout << "Hi World" << std::endl;
}
void CallPrint1()
{
PrintValue();
PrintHi();
}
void CallPrint2() const
{
PrintValue();
PrintHi(); //编译错误,error C2662: 'void CTest::PrintHi(void)': cannot convert 'this' pointer from 'const CTest' to 'CTest &'
}
int m_iValue;
mutable std::string m_strValue;
};
int main()
{
CTest Test1;
Test1.PrintValue();
Test1.ValueAdd1();
Test1.PrintValue();
Test1.PrintHi();
const CTest Test2;
Test2.PrintValue();
Test2.ValueAdd1();
Test2.PrintValue();
Test2.PrintHi(); //编译错误,error C2662: 'void CTest::PrintHi(void)': cannot convert 'this' pointer from 'const CTest' to 'CTest &'
system("pause");
}
为什么使用常成员函数?
我们定义的类的成员函数中,常常有一些成员函数不改变类的数据成员,也就是说,这些函数是"只读"函数,而有一些函数要修改类数据成员的值。如果把不改变数据成员的函数都加上const关键字进行标识,显然,可提高程序的可读性。其实,它还能提高程序的可靠性,已定义成const的成员函数,一旦企图修改数据成员的值,则编译器按错误处理。将成员函数声明为常成员函数也能防止产生const对象无法调用该成员函数的问题。