返回类型从
const Bar& getBar()
更改为 const Bar getBar()
。
如果我使用:
const auto& bar = getBar();
并且返回类型发生变化。我有一个临时对象的参考。
如果我使用:
const auto bar = getBar();
我总是复印
Bar
。
这个问题的最佳实践是什么?
class Bar {
public:
Bar() = default;
Bar(const Bar&) = default;
Bar(Bar&&) = delete;
Bar& operator=(const Bar&) = delete;
Bar& operator=(const Bar&&) = delete;
void setValue(int i);
int value() const;
private:
int m_i = 0;
};
class Foo {
public:
Foo(Bar& bar) : m_bar(bar) {}
Foo(const Foo&) = delete;
Foo(Foo&&) = delete;
Foo& operator=(const Foo&) = delete;
Foo& operator=(const Foo&&) = delete;
const Bar& giveMeBar();
private:
Bar& m_bar;
};
int main() {
auto bar = std::make_unique<Bar>();
auto foo = std::make_unique<Foo>(*bar.get());
const auto& barFromFoo = foo->giveMeBar();
bar->setValue(2);
std::cout << "original bar: " << bar->value() << std::endl;
std::cout << "bar from foo: " << barFromFoo.value() << std::endl;
}
实际上“最佳实践”是基于意见的。我只会尝试解释为什么你的前提不合理,这样你就可以自己对什么是好的做法提出自己的看法和/或可以就此事判断一些指导方针。
如果我使用:
并且返回类型发生变化。我有一个临时对象的参考。const auto& bar = getBar();
临时变量的生命周期被延长并绑定到常量引用。没有问题。如果您想避免不必要的副本,那么就不要制作副本。在显示的代码中,您可以将
const Bar& giveMeBar();
替换为 const Bar giveMeBar();
,没有任何问题。
为了便于说明,请考虑以下示例:
#include <iostream>
struct foo {
~foo(){ std::cout << "yes. I leave now. Bye\n";}
};
foo bar() { return foo{};}
int main() {
const foo& f = bar();
std::cout << "are you still there?\n";
}
输出:
are you still there?
yes. I leave now. Bye
PS:
auto
不会改变任何事情。以下是两两等效的:
const auto& barFromFoo = foo->giveMeBar();
const Bar& barFromFoo = foo->giveMeBar(); // same
// and
const auto barFromFoo = foo->giveMeBar();
const Bar barFromFoo = foo->giveMeBar(); // same