我目前正在开发一个c ++类。该类的目的是进行一些http查询。您创建指定
的实例使用此实例,您可以调用名为“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<Child> getChildren();
const std::list<Child> getChildren() const;
它将以两种方式编译,因为“getChildren”不会修改HttpRequest。
感谢您的帮助, 乌利
答案 0 :(得分:3)
const std::list<Child> getChildren();
const std::list<Child> getChildren() const;
它将以两种方式编译,因为“getChildren”不会修改HttpRequest。
不,它不会双向编译。 (如果愿意的话,那会有什么不同?)
第二种形式需要为getChildren()
对象(或引用或指针)调用const HttpRequest
:
void f(const HttpRequest& req)
{
const std::list<Child>& list = req.getChildren(); // requires const
// ...
}
这将需要尾随const
。
返回类型(const
)上的顶级const std::list<Child>
完全没有任何区别。返回的对象是右值。您可以做的就是制作副本或将其绑定到const std::list<Child>&
- 无论是const
还是getChildren()
。
您很可能不想在每次调用const std::list<Child>& getChildren() const;
时复制要复制的列表,因此您应该返回引用:
const
(当然,如果涉及异步,您可能希望复制,而不是分发对可能异步更改的对象的引用。)
您可以根据尾随const
重载。鉴于此,您可以有两个版本:一个用于更改列表,另一个用于获取const std::list<Child>& getChildren() const;
std::list<Child>& getChildren();
列表引用:
{{1}}
我不知道这对你的情况是否有意义。
答案 1 :(得分:2)
我最初的直觉反应是,如果难以决定,我们应该更详细地看一下这个功能。此外,由于HttpRequest
状态未发生变异,并且由于每次都可能返回不同的值,因此该函数可能根本不应该是成员。作为非成员,非朋友,使用HttpRequest
来执行其工作并返回值,这似乎更有意义。然后,const-semantics很清楚。
答案 2 :(得分:1)
一般的经验法则是,如果可以,将成员函数声明为const
。如果getChildren
进行了一些修改,似乎改变了它被调用的HttpRequest
对象的状态(即使它实际上没有改变状态),你可以将它声明为非const以避免混淆人。但除此之外,它应该是const
。
顺便说一句,我理解你为什么要将返回值声明为const
的逻辑。我仍然建议你不要这样做。使用C ++ 11和移动构造函数等,它实际上非常有用(并且更准确),因为它是非const的。
答案 3 :(得分:1)
如果您的目的是确保该函数不会更改HttpRequest对象的状态,那么您需要std::list<Child> getChildren() const
。除非您返回引用,否则没有理由使std::list
保持不变。