c++可以使用const关键字修饰对象,表明该对象为只读对象。只读对象的成员变量不允许被改变,程序中若改变只读对象那么编译阶段编译器将报错。
class cls
{
public:
int a;
cls() : a(6)
{}
void print();
void func();
};
void cls::print()
{
func(); //(3)报错error: passing ‘const cls’ as ‘this’ argument of ‘void cls::func()’ discards qualifiers
std::cout << "cls.a = " << a << std::endl;
}
void cls::func()
{
std::cout << "hello" << std::endl;
}
int main(void)
{
const cls c; //定义const属性的对象
c.print(); //(1)报错error: passing ‘const cls’ as ‘this’ argument of ‘void cls::print()’ discards qualifiers
//c.a = 8; //(2)报错error: assignment of data-member ‘cls::a’ in read-only structure
return 0;
}
(1) const对象只能调用const属性的成员函数,因为非const成员函数不能保证一定不修改对象(的成员变量)。
将print()赋予const属性:
class cls
{
//...
void print() const;
}
void cls::print() const
{
//...
}
注意,const成员函数的声明和定义都需要带上const。
(2) const对象的成员变量不允许被修改。
(3) const成员函数只能调用const成员函数。
下面看一个例子:
class cls
{
public:
int a;
//cls()
//{}
void print() const;
};
void cls::print() const
{
std::cout << "hello" << std::endl;
}
int main(void)
{
const cls c;
c.print();
return 0;
}
编译报错:
提示说没有初始化对象c。然后我尝试去除cls的空构造函数的注释:
class cls
{
public:
int a;
cls()
{}
};
编译正常通过:
只是定义一个空的构造函数,其实现体跟缺省的构造函数没什么两样,为什么就能使得程序编译通过其运行正常?
这是因为我们定义了一个const对象,const对象的数据成员在该对象的生命周期内都不能被改变,这就意味着,const对象的初始化只能在构造函数中。然而编译器知道,缺省的构造函数是不做任何实质性的操作的,对对象的初始化操作只能依靠用户自定义的构造函数,所以当我们程序中没有定义构造函数的时候程序编译报错。
编译器认为用户定义了构造函数了,便会在该函数中对对象进行初始化,然后我们实际并没有,所以说,这是代码对编译器的一种欺骗行为。一般我们不能采取这种操作!