关于const实例方法的最佳实践是什么?

时间:2009-06-25 20:14:12

标签: c++ const

根据接受的答案指出,从const实例方法返回一个非const引用的成员将无法编译(没有强制转换或使成员变量可变),这个问题变得更加普遍-practices讨论const实例方法。

对于后代,这是原始问题:

如果我有一个带有getter的对象,它返回一个非const引用,例如:

SomeObject& SomeOtherObject::foo(){
   return someObjectInstance;
}

这应该是const吗?显然调用本身不会修改对象,但调用者可以修改someObjectInstance,这会改变我的SomeOtherObject实例。

我想我的问题实际上归结为“成员方法上const究竟是什么意思?”是否A)调用本身不会改变对象或B)没有突变对象可以在调用期间发生,也可以作为返回的引用/指针的结果(对于执行const_casts的人有一个警告)。

顺便说一下,我现在正在添加这个我需要const调用的地方。

 const SomeObject& SomeOtherObject::constFoo() const{
   return someObjectInstance;
}

为了安全起见,因为我不愿意这样做

 SomeObject& SomeOtherObject::foo() const{
   return someObjectInstance;
}

即使它会让我的生活在某些地方变得更轻松。

6 个答案:

答案 0 :(得分:4)

const (当应用于成员函数时)主要用作自我文档的手段。它与调用代码的契约是该函数不会修改外部状态(即没有可观察到的副作用)。

编译器通过在const成员函数内部使所有成员有效const来实现这一点

看到类似的代码并不罕见:

const SomeObject& SomeOtherObject::constFoo() const;
SomeObject& SomeOtherObject::constFoo();

以下内容无法编译(MSVC 9和gcc 3.4.4)

SomeObject& SomeOtherObject::constFoo() const{
  return someObjectInstance;
}

你可以通过抛弃const来解决上述错误:

SomeObject& SomeOtherObject::constFoo() const{
  return (SomeObject&)someObjectInstance;
}

但这当然会破坏与您的代码用户的合同,您不会更改SomeOtherObject实例。

您也可以使someObjectInstance mutable 能够避免强制转换,但最终它确实没有更好。

答案 1 :(得分:2)

回答你的问题:

  

“会员身上的const究竟是什么   方法意味着什么?“

这意味着该方法可以安全,合理地应用于const对象。的 当然,“安全”和“理智”意味着什么将取决于您的类模型的问题域。

您可能还想考虑让访问者返回值而不是引用。如果他们必须返回参考文献,那么我会重新考虑我的整体设计。

答案 2 :(得分:1)

如果你有一个对象,并在处理过程中调用任意数量的const方法,那么可观察的行为不会改变,我会说。

标准(9.3.2,第2段)说“在const成员函数中,调用函数的对象是通过const访问路径访问的;因此{{1成员函数不得修改对象及其非静态数据成员。“这也意味着你不能通过正常的const-correctness规则返回非const引用或指针。

(这并不意味着类的内部不能更改;标准具有const关键字来指定可以在mutable函数中更改的成员数据。)

答案 3 :(得分:0)

  

“会员身上的const究竟是什么   方法意味着什么?“

这意味着该方法不会更改特定类的成员变量。另外,使用const不允许该方法调用另一个非const方法。

它用于可读性和清晰度,以及它的安全性,可以直接或通过调用可能的其他方法进行意外更改。

答案 4 :(得分:0)

const的语义取决于问题域。如果它可能含糊不清,请记录下来。

例如,如果你有一个包装对数据库的访问权限的类,那么将“const”方法改为那些不改变数据库状态的方法是完全合理的,即使它们可能会改变一些隐藏的对象内部状态(使用'mutable'关键字来允许这个)。

答案 5 :(得分:0)

  

成员方法的const究竟是什么意思?

这意味着您保证不会修改函数中的任何非可变成员数据。换句话说,它意味着隐含的this指针指向const对象。

恕我直言,将非const引用返回给私有成员数据是不好的做法。它为您的班级用户打开了大门,无需通过公共界面即可修改其内部。