假设我们有一个 myType 类型的对象 obj,并且我们希望将其传递给函数 Foo,该函数返回一些有关 obj 的有价值的信息。函数 Bar 是声明 obj 的地方,也是从中调用 Foo 的地方,如下所示:
void Bar ()
{
myType obj; //default constructor
string valuableInfo = Foo(obj);
//do other stuff
//...
} //end of Bar()
当然,这段代码并没有过多说明 Foo 是否将 obj 作为引用或值,以及 Foo 是否以任何方式修改 obj。
当然,如果 Food 将对象作为值或 const 引用,我们就不会有任何问题。
string Foo (const myType & input); //this is fine
string Foo (myType input); //so is this
但我们不能保证这一点!函数签名很可能是
string Foo (myType & input); //asking for trouble!!
但是检查我们想要传递 obj 的每个函数的签名非常不方便,那么我们如何指定我们只想将对象传递给承诺不修改它的函数呢?
当然,一种方法是将 obj 声明为 const,但这种方法的问题是我们失去了灵活性。如果我们想在调用 Foo(obj) 后修改 Bar() 中的 obj 该怎么办?
void Bar ()
{
const myType obj; //default constructor
string valuableInfo = Foo(obj); //compiler will complain if Foo's signature doesnt match
//we can't modify obj here :(
//...
} //end of Bar()
显而易见但糟糕的解决方案是这样做:
void Bar ()
{
myType obj; //default constructor
const myType immutableObj {obj}; //copy ctr call
//this is expensive and not recommended if obj is big! want to avoid
string valuableInfo = Foo(immutableObj); //will get the valuable Info risk free
// compiler will complain if Foo has inappropriate signature
//do other stuff
//...
} //end of Bar()
那么这里最好的解决方案是什么?有没有办法静态断言 Foo 对我们传入的对象是非侵入性的?我们可以暂时将 obj 设置为 const (无需创建新的 const 对象)或达到此效果吗?