C ++:这是一个有效的常量成员函数吗?

时间:2011-09-22 13:48:07

标签: c++ methods const member

我目前正在开发一个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。

感谢您的帮助, 乌利

4 个答案:

答案 0 :(得分:3)

  
      
  • const std::list<Child> getChildren();
  •   
  • const std::list<Child> getChildren() const;
  •   
     

它将以两种方式编译,因为“getChildren”不会修改HttpRequest。

  1. 不,它不会双向编译。 (如果愿意的话,那会有什么不同?) 第二种形式需要为getChildren()对象(或引用或指针)调用const HttpRequest

    void f(const HttpRequest& req)
    {
       const std::list<Child>& list = req.getChildren(); // requires const
       // ...
    }
    

    这将需要尾随const

  2. 返回类型(const)上的顶级const std::list<Child>完全没有任何区别。返回的对象是右值。您可以做的就是制作副本或将其绑定到const std::list<Child>& - 无论是const还是getChildren()

  3. 您很可能不想在每次调用const std::list<Child>& getChildren() const; 时复制要复制的列表,因此您应该返回引用

    const

    (当然,如果涉及异步,您可能希望复制,而不是分发对可能异步更改的对象的引用。)

  4. 您可以根据尾随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保持不变。