在我维护的项目中,我看到很多类似的代码用于简单的get
/ set
方法
const int & MyClass::getFoo() { return m_foo; }
void MyClass::setFoo(const int & foo) { m_foo = foo; }
这样做有什么意义而不是以下几点?
int MyClass::getFoo() { return m_foo; } // Removed 'const' and '&'
void MyClass::setFoo(const int foo) { m_foo = foo; } // Removed '&'
传递对基本类型的引用应该需要与传递类型值本身相同(或更多)的努力,对吧?
毕竟这只是一个数字...
这只是一些尝试的微观优化还是有真正的好处?
答案 0 :(得分:20)
不同之处在于,如果您自己将结果导入引用,则可以在不调用函数的情况下跟踪自己的变量名中整数成员变量的更改。
const &int x = myObject.getFoo();
cout<<x<<endl;
//...
cout<<x<<endl;//x might have changed
它可能不是最好的设计选择,如果返回从范围中释放的变量,则返回引用(const或不是const)非常危险。因此,如果您返回引用,请注意确保它不是超出范围的变量。
修饰符也略有不同,但可能不值得做或想要的事情。
void test1(int x)
{
cout<<x<<endl;//prints 1
}
void test2(const int &x)
{
cout<<x<<endl;//prints 1 or something else possibly, another thread could have changed x
}
int main(int argc, char**argv)
{
int x = 1;
test1(x);
//...
test2(x);
return 0;
}
因此,最终结果是即使在传递参数后也会获得更改。
答案 1 :(得分:7)
对我来说,为原语传递 const引用是一个错误。您需要修改该值,在这种情况下,您传递非const引用,或者您只需要访问该值,在这种情况下,您传递 const
Const引用只应用于复杂类,因为复制对象可能是性能问题。对于基元,除非您需要修改变量的值,否则不应传递引用。原因是引用比非引用花费更多的计算时间,因为使用引用,程序需要在表中查找才能找到对象的地址。当查找时间短于复制时间时,引用是一种改进。
通常, ints 和地址在低级实现中具有相同的字节长度。因此,复制 int 作为函数返回值的时间等同于复制地址的时间。但是如果返回 int ,则不会执行查找,因此性能会提高。
答案 2 :(得分:5)
返回值和返回const引用之间的主要区别在于,您可以const_cast引用并更改值。
这是糟糕设计的一个例子,并试图创建一个简单而简洁的设计绰绰有余的智能设计。作者不仅仅返回一个值,而是让代码的读者思考他可能有什么意图。
答案 3 :(得分:4)
没有太大的好处。我之前在框架或宏生成的getter和setter中看到了这一点。宏代码没有区分原始类型和非POD类型,只是在整个板上使用const type&
作为setter。我怀疑这是效率问题还是真正的误解;这是一个一致性问题。
答案 4 :(得分:2)
我认为编写这类代码的人误解了引用的概念,并将其用于包括原始数据类型在内的所有内容。我也看过这样的代码,看不出这样做有什么好处。
答案 5 :(得分:0)
除了
之外没有任何意义和好处void MyClass::setFoo(const int foo)
void MyClass::setFoo(const int& foo)
因为那时你将无法在'setFoo'实现中重用'foo'变量。我相信'int&amp;'只是因为Guy习惯于通过const引用来传递所有东西,并且没有任何问题。