c ++ const成员函数返回对类成员的引用

时间:2014-05-06 07:23:47

标签: c++ reference

如果我有类成员函数:

bar* foo::get_value() const
{
  return &_value;
}

编译器会抱怨

  

无法使用类型为const bar *

的rvalue初始化bar *类型的变量

_value在课程中不是const

如果我有这个功能:

bar* foo::get_value() const
{
  return const_cast<bar *>(&_value);
}

它运作得很好。

我认为声明成员函数常量意味着您承诺不修改类的内部内容,但操作&似乎在const成员函数中返回一个常量指针。这是为什么?

4 个答案:

答案 0 :(得分:5)

当您声明函数const时,您说这是一个在对象的非const和const实例上都允许的函数。因为它可以在const实例上调用,所以该函数不应该改变该对象。当您向内部对象返回非const引用时,您将为调用者提供一种间接改变对象内部状态的方法。要解决此问题,请返回一个常量对象。

换句话说,而不是:

Bar* Foo::GetBar() const

执行:

const Bar* Foo::GetBar() const

或者,更好的是:

const Bar& Foo::GetBar() const

正如您所观察到的,const_cast允许您破坏对象的常量。通常,您应该避免使用const_cast;使用它是一种代码气味,它破坏了预期的const保证。

答案 1 :(得分:1)

问题是getter函数的返回类型。您将返回bar*而不是const bar*。前者允许get_value函数的调用者修改对象。但是,您明确禁止将_value声明为const

您可以使用const_cast绕过它,但它不正确。这就像告诉编译器“相信我,我知道我在做什么”,但在这种情况下,你没有。您无法控制调用代码将对该对象执行的操作。如果他们试图修改它 - bam,未定义的行为。

让自己变得简单,只需让getter返回const bar*

const bar* foo::get_value() const
{
  return &_value;
}

请注意,编译器错误消息实质上告诉您需要对代码进行更改。

答案 2 :(得分:1)

const成员函数仅适用于const对象。使用const对象,您无法更改其成员变量。这就是为什么编译器不允许你创建一个指向const对象的成员变量的非const指针。

答案 3 :(得分:1)

当一个对象实例被声明为const时,它被视为所有成员变量也是const - 也就是说,除了使用关键字{{'声明的成员之外1}}。

因此,从理论上讲,您可以将mutable声明为_value,这至少会比mutable略微优于const_cast<>。但它仍然不理想。正确的方法是提供两个重载:

const bar* foo::get_value() const
{
    return _value;
}

bar* foo::get_value()
{
    return _value;
}

(更好的是使用引用或智能指针而不是原始指针)。