根据接受的答案指出,从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;
}
即使它会让我的生活在某些地方变得更轻松。
答案 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引用返回给私有成员数据是不好的做法。它为您的班级用户打开了大门,无需通过公共界面即可修改其内部。