C++:这是一个有效的常量成员函数吗?
我目前正在研究 C++ 课程。该类的目的是进行一些 http 查询。您创建一个指定
- 目标 url 和
- 其他一些参数的
实例。使用此实例,您可以调用名为“getChildren”的方法,该方法连接到 HTTP 服务器、执行查询并返回子级列表。基本上,它看起来与此类似:
class HttpRequest
{
public:
// omitted constructor, ...
const std::list<Child> getChildren() {
// do the http query
// build a list
return(list);
}
}
“getChildren”返回的列表可能会因每次调用而更改 - 取决于 HTTP 服务器上执行的其他操作。现在您的意见是什么:我该如何声明该方法:
const std::list
; getChildren(); const std::list
; getChildren() const;
它将以两种方式编译,因为“getChildren”不会修改 HttpRequest。
感谢您的帮助, 乌里
I'm currently working on a c++ class. The purpose of the class is to do some http queries. You create an instance specifying
- destination url
- some other parameters
With this instance, you can call a method called "getChildren" which connects to the HTTP server, executes a query and returns a list of children. So basically, it looks similar to this:
class HttpRequest
{
public:
// omitted constructor, ...
const std::list<Child> getChildren() {
// do the http query
// build a list
return(list);
}
}
The list which is returned by "getChildren" might change for each call - depending on other actions done on the HTTP server. Now what's your opinion: How shall I declare the method:
const std::list<Child> getChildren();
const std::list<Child> getChildren() const;
It will compile in both ways, since "getChildren" doesn't modify HttpRequest.
Thanks for your help,
Uli
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
不,它不会以两种方式编译。 (如果是的话,那会有什么区别呢?)
第二种形式需要为
const HttpRequest
对象(或引用或指针)调用getChildren()
:这需要尾随
const
。返回类型上的顶级
const
(const std::list
) 没有任何区别。返回的对象是右值。您所能做的就是制作一个副本或将其绑定到const std::list&
- 无论它是否是const
。您很可能不希望每次调用
getChildren()
时都复制此类列表,因此您应该返回一个引用:(当然,如果涉及异步,您可能想要复制,而不是分发对可能异步更改的对象的引用。)
您可以根据尾部
const
进行重载。鉴于此,您可以有两个版本:一个用于更改列表,另一个用于获取const
列表引用:我不知道这对你的情况是否有意义。
No, it will not compile both ways. (If it would, what would that difference be there for?)
The second form is required to call
getChildren()
forconst HttpRequest
objects (or references or pointers):This would require the trailing
const
.The top-level
const
on the return type (const std::list<Child>
) makes no difference at all. The returned object is an rvalue. All you can do with it is to make a copy or bind it to aconst std::list<Child>&
- no matter whether it'sconst
or not.You very likely do not want to copy such lists to be copied each time
getChildren()
is called, so you should return a reference:(Of course, if there is asynchrony involved, you might want to copy, rather than hand out references to a potentially asynchronously changing object.)
You can overload based on the trailing
const
. Given that, you could have two versions: one for changing the list and one for getting aconst
list reference:I wouldn't know whether this makes any sense in your case.
我最初的直觉反应是,如果很难决定,我们应该更详细地研究该函数。此外,由于
HttpRequest
状态不会发生变化,并且每次可能返回不同的值,因此该函数可能根本不应该是成员。看起来,作为一个非成员、非朋友,使用 HttpRequest 来执行其工作并返回一个值可能更有意义。那么常量语义就清楚了。My initial gut reaction here is that if it's hard to decide, we should look at the function in more detail. Also since the
HttpRequest
state isn't mutated, and since it may return a different value each time, perhaps the function shouldn't be a member at all. It seems that it might make more sense as a non-member, non-friend that makes use of theHttpRequest
to perform its work and return a value. Then the const-semantics are clear.一般的经验法则是,如果可以的话,将成员函数声明为 const。如果
getChildren
进行了一些修改,似乎改变了它所调用的HttpRequest
对象的状态(即使它实际上没有改变状态),您可能应该声明它非常量以避免让人们感到困惑。但除此之外,它应该是 const。顺便说一句,我理解为什么您将返回值声明为 const 的逻辑。我仍然建议你不要这样做。对于 C++11 和移动构造函数等,它实际上非常有用(而且更准确),因为它是非常量的。
A general rule of thumb is declare a member function to be
const
if you can. IfgetChildren
makes some modification that appears to change the state of theHttpRequest
object it's called on (even if it doesn't actually change the state) it's possible you should declare it non-const to avoid confusing people. But otherwise, it should beconst
.As an aside, I understand the logic of why you're declaring the return value to be
const
. I would still suggest you not do that. With C++11 and move constructors and such, it's actually very useful (and more accurate) for it to be non-const.如果您的目的是确保该函数不会更改 HttpRequest 对象的状态,那么您需要
std::list; getChildren() const
。没有理由使 std::list 常量,除非您返回引用。If your intent is to make sure that the function does not change the state of the HttpRequest object, then you want
std::list<Child> getChildren() const
. There is no reason to make thestd::list
constant, unless you return a reference.