【发布时间】:2015-12-05 07:04:40
【问题描述】:
假设我们有一个 myType 类型的 Object obj,我们想将它传递给函数 Foo,它会返回一些关于 obj 的有价值的信息。函数 Bar 是声明 obj 的地方,也是从那里调用 Foo 的地方:
void Bar ()
{
myType obj; //default constructor
string valuableInfo = Foo(obj);
//do other stuff
//...
} //end of Bar()
这段sn-p的代码当然并没有过多地说明Foo是否将obj作为引用或作为值,以及Foo是否以任何方式修改了obj。
当然,如果 Foo 将 obj 作为值或 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 对象)或类似的东西吗?
【问题讨论】: