什么时候应该有一个成员函数有一个const限定符,什么时候不应该呢? [英] When should a member function have a const qualifier and when shouldn't it?

查看:133
本文介绍了什么时候应该有一个成员函数有一个const限定符,什么时候不应该呢?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大约六年前,一位名为Harri Porten的软件工程师撰写了这篇文章,问什么时候一个成员函数有一个const限定符,什么时候不应该呢?我发现这是最好的写作,我可以找到的问题,我一直在与最近争执,我认为在大多数讨论我没有很好地覆盖了const正确性。因为一个像SO这样强大的软件信息共享站点当时没有,所以我想在这里复活这个问题。

About six years ago, a software engineer named Harri Porten wrote this article, asking the question, "When should a member function have a const qualifier and when shouldn't it?" I found it to be the best write-up I could find of the issue, which I've been wrestling with more recently and which I think is not well covered in most discussions I've found on const correctness. Since a software information-sharing site as powerful as SO didn't exist back then, I'd like to resurrect the question here.

推荐答案

这篇文章似乎覆盖了很多基础,但作者仍然有一个关于const和非const的重载函数返回指针的问题。文章的最后一行是:

The article seems to cover a lot of basic ground, but the author still has a question about const and non-const overloads of functions returning pointers. Last line of the article is:

很多人可能会回答这取决于。但是我想问这取决于什么?

为了绝对精确,它取决于A对象指针的状态是逻辑对象的状态的一部分。

To be absolutely precise, it depends whether the state of the A object pointee is logically part of the state of this object.

对于一个示例, ; int> :: operator [] 返回对int的引用。 int引用是向量的部分,尽管它实际上不是数据成员。因此,const-overload成语适用于:更改一个元素,并且你已经改变了向量。

For an example where it is, vector<int>::operator[] returns a reference to an int. The int referand is "part of" the vector, although it isn't actually a data member. So the const-overload idiom applies: change an element and you've changed the vector.

对于不是的例子,考虑 shared_ptr 。这有成员函数 T * operator->()const; ,因为有一个常见的智能指针 -const 对象。引用不是智能指针的一部分:修改它不会更改智能指针。所以,你是否可以重置一个智能指针来引用一个不同的对象的问题是独立的,不管是否是const。

For an example where it isn't, consider shared_ptr. This has the member function T * operator->() const;, because it makes logical sense to have a const smart pointer to a non-const object. The referand is not part of the smart pointer: modifying it does not change the smart pointer. So the question of whether you can "reseat" a smart pointer to refer to a different object is independent of whether or not the referand is const.

我不认为我可以提供任何完整的指南,让您决定是否pointee逻辑上是对象的一部分或不。但是,如果修改pointee改变 this 的任何成员函数的返回值或其他行为,特别是如果pointee参与 operator == ,那么很可能是它在逻辑上是这个对象的一部分。

I don't think I can provide any complete guidelines to let you decide whether the pointee is logically part of the object or not. However, if modifying the pointee changes the return values or other behaviour of any member functions of this, and especially if the pointee participates in operator==, then chances are it is logically part of this object.

假设的一侧是部分(并提供重载)。然后如果出现编译器提示我正在修改从一个const对象返回的A对象的情况,我会考虑我是否真的应该这么做,如果这样改变设计,只有指针到A 在概念上是对象状态的一部分,而不是A本身。这当然需要确保修改A不会破坏这个 const对象的预期行为。

I would err on the side of assuming it is part (and provide overloads). Then if a situation arose where the compiler complains that I'm trying to modify the A object returned from a const object, I'd consider whether I really should be doing that or not, and if so change the design so that only the pointer-to-A is conceptually part of the object's state, not the A itself. This of course requires ensuring that modifying the A doesn't do anything that breaks the expected behaviour of this const object.

如果你发布的接口,你可能必须提前搞清楚,但实际上从const重载到const函数返回非常量指针不太可能破坏客户端代码。无论如何,当你发布一个界面,你希望有一点,它可能会感觉到你的对象的状态真正包括。

If you're publishing the interface you may have to figure this out in advance, but in practice going back from the const overloads to the const-function-returning-non-const-pointer is unlikely to break client code. Anyway, by the time you publish an interface you hopefully have used it a bit, and probably got a feel for what the state of your object really includes.

Btw,I也试图在不提供指针/引用访问器,特别是可修改的一侧。这真的是一个单独的问题(德米特法和所有),但是你可以更换次数:

Btw, I also try to err on the side of not providing pointer/reference accessors, especially modifiable ones. That's really a separate issue (Law of Demeter and all that), but the more times you can replace:

A *getA();
const A *getA() const;

A getA() const; // or const A &getA() const; to avoid a copy
void setA(const A &a);

您不必担心这个问题。当然后者有自己的限制。

The less times you have to worry about the issue. Of course the latter has its own limitations.

这篇关于什么时候应该有一个成员函数有一个const限定符,什么时候不应该呢?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆