一个const的对象,调用自身用该都是const式的成员函数,因为非const成员函数可能会更改该对象,与const对象冲突。当然可以加上一个-fpermissive参数来稍微放松,但最好不要这样做。
右值作为一个非const引用参数,编译器不允许。
左值:可以取到地址并且有空间,内容可以改变的。
右值:1.不可取地址,如常量1,2,3等。2.可以取地址但是该空间不可更改,如const 值,构造函数。3.本身就是常量值,如int test[4],test本身就是一个地址常量值,内部就是一个test指针变量,但该变量为const类型,可以归结到第二点。
注:该规则仅仅是对于**引用 &**来说。
类Lit
const Lit a = Lit();
Lit b = a; //ok,仅仅是值的复制而已
Lit &b = a; //error,因为b改变了,a就改变,但a是const的,冲突。
像这种情况:
void fun(Lit & l){...}
int main()
{
1.fun( Lit() ); //error,因为Lit()构造函数返回为右值
2. Lit temp = Lit();
fun( temp ) //ok,因为temp是一个左值
}
解除这种限制就是void fun( const Lit & l)
可以接受任何形式的Lit。
如果要返回Lit 如
const Lit & fun(const Lit & l){ return l; } //ok
Lit & fun( const Lit & l) { return l; } //error
Lit fun(const Lit & l) { return l; } //ok此时会创建临时区域,仅仅是普通相对费时复制而已。
一种伪装式的临时变量
class Lit
{
string s;
public:
Lit(string _s) : s(_s) {}
...;
string getString() { return s; }
};
const Lit & Mid( const Lit & l )
{
return l;
}
const Lit & returnLit()
{ return Mid( Lit("hello") ); }
此函数若写成这样
const Lit & returnLit()
{ Lit a("hello"); return Mid(a); }两者运行都会报错
若是在Lit a("hello"); 加上static 那么就不会报错。即该对象会一直存在。
int main()
{
const Lit & test = returnLit();
string s = test.getString();
cout<<s<<endl;
return 1;
}
这种伪装式的变成风格编译器不会报错也不会警告,但是运行起来就会报段错误,这说明了不要去返回临时变量的引用。但在现实情况使用构造函数去给某个函数初始化的比比皆是,而以返回类引用函数形式的编程也比比皆是,就Mid函数来说,本身是完全正确的,而且是值得推荐的。对于某些GUI编程,设置一些东西常常使用构造函数,其实这些函数一般不会返回什么东西,他仅仅是作为设置来用。所以也没多大事。怎么说呢,当规模很大的时候,可能不经意或者设计的疏忽,会发生这种大问题。我觉得使用也要像使用指针那样小心为是,其实BJ也说就把它当做为const式的指针来考虑。