Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/140.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 我可以有一个const member函数返回*this并处理非常量对象吗?_C++ - Fatal编程技术网

C++ 我可以有一个const member函数返回*this并处理非常量对象吗?

C++ 我可以有一个const member函数返回*this并处理非常量对象吗?,c++,C++,如果我理解正确,不应该修改对象的成员函数应该声明为const,以让用户知道保证。现在,当该成员函数返回对*this的引用时会发生什么?例如: class C{ public: C &f() const {return *this;} }; 在C::f()内部,此的类型为const C*,因此,以下内容将不会编译: int main() { C c; // non-constant object! c.f(); return 0; } 当然,我们可以提供

如果我理解正确,不应该修改对象的成员函数应该声明为
const
,以让用户知道保证。现在,当该成员函数返回对
*this
的引用时会发生什么?例如:

class C{
public:
    C &f() const {return *this;}
};
C::f()
内部,
的类型为
const C*
,因此,以下内容将不会编译:

int main() {
    C c; // non-constant object!
    c.f();
    return 0;
}
当然,我们可以提供非常量版本的
C::f()
来处理非常量对象:

class C{
public:
    const C &f() const;
    C &f();
};
然而,我不相信这是我们想要的。请注意,非常量版本不会更改对象,但不会表达对用户的承诺。。。我错过什么了吗

编辑:为了清楚起见,让我总结一下这个问题:
f()
不修改调用它的对象,因此将其声明为
C&f()未使其成为
常量
成员是误导性的。另一方面,我确实希望能够在非常量对象上调用
f()
。我如何解决这种情况


编辑:从评论中的所有讨论中可以看出,该问题是基于对函数成员的
const
ness含义的错误理解。我对自己的正确理解是:


返回非常量引用的成员函数旨在允许其用户通过返回的引用更改对象。因此,即使此函数本身不会更改对象,也不应倾向于将其声明为
const
成员

您的问题是原始函数定义:

C &f() const {return *this;}
在这里,您返回一个对const对象的非const引用,这将允许更改const对象,这将是危险的,因此是禁止的

如果你把它写成

const C &f() const {return *this;}
将可从常量和非常量对象调用,并始终返回常量引用

当然,我们可以提供C::f()的非常量版本来处理非常量对象。然而,我不相信这是我们想要的


也许这正是你想要的。这是在非常量对象上调用时返回非常量引用并在常量对象上调用它时保持常量正确性的唯一方法。

您在原始函数声明中遗漏了
const
:“const C&f()const”。否则该函数就没有意义-const函数返回对象可以修改如果返回非const引用,则意味着该函数将用于修改对象。。。你的选择是
C&f()
C const&f()const
,或者两者兼而有之。我意识到了这一切。但这正是我的问题:
f()
不会修改对象,因此将其声明为
C&f()
而不使其成为
const
是误导性的。另一方面,我确实希望能够在非常量对象上调用
f()
!拥有
C&f()并不误导人
但是假设我有一个非常量成员
g()
属于同一个类,并且用户想要编写
c.f().g()
。我可以启用它吗?@MeirGoldenberg否,非常量函数可能会修改它,并且不允许对返回的常量引用调用它。如果
g()
没有修改它,它可能应该被标记为const。我意识到如果
f()
返回一个const引用,那么写这样的东西是被禁止的。但是,我认为用户在同一对象上依次调用
f()
g()
并保证
f()
不会更改对象的意图没有任何错误。如果用户的意图没有任何错误,那么我不能以一种能让他这样做的方式编写类就没有意义了。@MeirGoldenberg你太在意这个“不会改变对象”的误解了。试着忘记这一点。将
const
方法视为含义:可以在
const
对象上调用。@MeirGoldenberg问题是,虽然函数可能不会直接修改对象,但它会允许所有其他代码通过返回的引用对其进行修改。允许任何其他代码修改对象的函数不是常量。在本例中,允许其他代码更改对象与直接更改代码相同。