【问题标题】:Returning a reference from a constant function从常量函数返回引用
【发布时间】:2009-01-29 04:36:17
【问题描述】:
#include "iostream"
#include "vector"
class ABC {
};
class VecTest {
std::vector<ABC> vec;
public:
std::vector<ABC> & getVec() const { //Here it errors out
return vec;
}
};
删除 const 修复它,不是 getVec 是一个常量方法吗?那么为什么不允许这样做呢?
【问题讨论】:
标签:
c++
methods
constants
【解决方案1】:
您可能应该做的是返回一个 const 引用。
const std::vector& getVec() const { return vec; }
这是不允许的,因为您说过 getVec 是一个 const 方法,这意味着该方法不应以任何方式更改 this 对象。返回非常量引用可能会允许其对象被更改,因此编译器不允许这样做。
【解决方案2】:
如果一个方法是 const 则它向编译器保证,对象的状态不能通过调用该方法来改变。
如果方法返回对内部成员的引用,那么方法的用户可以通过引用间接改变对象的状态。
所以实际上 const 方法不能返回引用(因为它允许间接更改对象的状态)。您可以做的是返回一个 const 引用。从而允许用户访问内部成员但维护成本合约。
例子:
class X
{
int& getX(); // get a reference to X
int const& getX() const; // get a reference to X BUT the interface guarantees
// the object will not change state.
private:
int x;
};
另一种看待它的方式。
如果你有一个 const 对象。 仅允许您调用 const 方法。如果通过调用 const 方法可以检索对对象内部成员的引用,则可以更改其状态。这将违反原始对象的 const(ness)。
【解决方案3】:
getVec()的返回类型需要为const std::vector<ABC>&。
【解决方案4】:
为了补充已经说过的内容,当你创建一个 const 方法时,它获得的对象实例(this 指针)本质上变成了 const。请记住,当您返回 vec 时,您会隐式返回 this->vec:
return this->vec; // it's a const std::vector<ABC> since "this" is const
“Constness”不能被取消——除非你用const_cast<> 明确地取消它。
// to illustrate what's happening when you're returning from the function
std::vector<ABC> &return = this->vec; // can't assign const to non-const!
因此,您的返回类型也必须是 const:
const std::vector<ABC> &return = this->vec; // all is good
【解决方案5】:
补充一下Ray Hidayat 所说的,一个 const 方法只能对类成员进行 const 访问。您正在尝试返回对 const 成员变量的非 const 引用,因此它失败了。
如果您确实需要从 const 函数访问成员变量的可修改版本,您可以将变量声明为可变。不过我不会推荐它。