代码之家  ›  专栏  ›  技术社区  ›  hookenz

C++中使用const的正确方法是什么?

  •  5
  • hookenz  · 技术社区  · 14 年前

    常量的正确性让我有些困惑。

    你用什么样的经验法则来决定什么时候某样东西应该是常量?

    e、 g.考虑这个例子

    class MyClass
    {
      string ToString(); // this one?
      const string& ToString(); // or this? 
      const string& ToString() const; // or this?
    
      char* ToString(); // What about this?
      const char* ToString(); // or this?
      const char* ToString() const; // or this?
      const char const* ToString(); // Is this legal?
      const char const* ToString() const; // how about this?
      char const* ToString();  // or even this?
    };
    

    警察会很困惑的。

    所有这些ToString方法有什么区别?

    如果我理解正确,第一个返回一个可以修改的新字符串对象 如果需要的话。 第二个返回常量引用,可能应该是string const&ToString()。 第三个可能是胡说八道,因为引用总是不变的,对吗?

    我想我应该把旧的char*版本放进去比较,因为我有返回对象指针的方法,我不确定它们是否应该是const。

    我想我只是想了解const正确性的局限性和好处,以及如何预先决定某个东西是否应该是const,以及如何正确应用const,因为将const放在不同的地方会改变其含义。

    编辑:还有,我该怎么处理。。。丢弃限定符。那到底是什么意思?

    6 回复  |  直到 14 年前
        1
  •  2
  •   Zooba Necrolis    14 年前

    const 取决于函数的用途。正如詹姆斯在他的评论中所建议的那样(这是一个值得回答的问题),把 常量 你可以在任何地方:

    如果函数要修改其对象实例中的状态, 常量

    如果函数要修改其引用或指针参数之一, 不要 常量 在参数上。

    如果变量 应该修改指针或引用, 不要 常量 在类型上(记住, 常量 适用于定义的前一部分)。

    常量 在类型上。

    如果不知道 目的 功能。我倾向于使用 string ToString() const char* ToString() const ,关于谁负责的文件非常清楚 delete char*


    作为补充说明, const char* char const* char* const

        3
  •  0
  •   aschepler    14 年前

    不能重载具有相同名称和参数但返回类型不同的函数。你可能知道,但只是确定。

    const 之后 () ToString 不会更改对象,因此在所有情况下都可能需要const方法。

    返回之间的区别 string 然后回来 const string& 一串 对象(例如,作为 MyClass 一串 按价值计算。

    一串 对象通常比使用C样式更可取 char* 指针,但是既然你问:第四个, ,会让其他代码更改返回字符串中的字符,这可能是件坏事。 const char* , char const* const char const* 都是一样的。 char *const const int 无关紧要:调用者只需复制并更改返回值。

    简而言之,最好的形式是:

    const string& ToString() const;
    string ToString() const;
    const char* ToString() const;
    
        4
  •  0
  •   Arun    14 年前

    问题的一些变化是关于返回 string char * . 我认为这与 const 一串 返回变量。

    class MyClass
    {
      string ToString();              // A
      string & ToString();            // B   (I added this)
      const string& ToString();       // C 
      const string& ToString() const; // D
    };
    

    在所有的变化中, 有两种用法:

    • 常量

      这意味着返回的对象不能用于修改返回的对象。这句话听起来很有趣,不是吗?可能还有其他方法可以修改一个对象 无法阻止。看这个 FAQ item .

    • 类不变量[第二个 在D中]

      这意味着该方法不会改变(修改)类对象。

    但是如果这个物体 必须修改 (也就是说,如果不修改对象,就不可能实现该方法),那么就排除了D。

    在其余部分中,B和C都比A更可取,因为B和C返回一个引用,从而避免了A中所需的副本构造。

    在B和C之间,C更可取,因为它返回a 参考资料。

        5
  •  -1
  •   Jeff Barger    14 年前

    this 做一个有用的向导

        6
  •  -1
  •   André Caron    14 年前

    你用什么样的经验法则来决定什么时候某样东西应该是常量?

    你可以在任何地方使用它。那么, 不要 在nedd修改对象或授予访问可能修改对象的权限(即将引用或代理返回到内部状态)时使用它。

    第三个可能是胡说八道,因为引用总是不变的,对吗?

    不,那是不对的。引用是别名,而不是变量。因此,不能像使用指针一样更改引用“指向”哪个变量。但是,您可能有对可变对象的引用( std::string&

    所有这些ToString方法有什么区别?

    它们在内存管理技术上都有很大的不同,但在高级别上,它们都做相同的事情,除了以下几点:

    char* ToString();
    

    可变的 字符数组(可能是内部状态)。

    请注意,家庭成员:

    char const* ToString();
    const char* ToString(); // or this?
    const char const* ToString(); // Is this legal?
    

    以下两种方法是首选的方法(提供额外的 const 在C++中返回字符串的结尾:

    string ToString(); // this one?
    const string& ToString(); // or this?
    

    你将使用哪一个取决于你从哪里得到的价值。如果字符串是一个数据成员,我建议您使用后者,因为后者通常更快,但如果字符串实现使用写时复制语义,则不会太快。如果必须计算一个值并返回它,则必须使用前者,因为不能返回对局部变量的引用。

    std::string

    const char* ToString() const; // or this?
    const char const* ToString() const; // how about this?
    
    推荐文章