Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/146.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 常量正确性的定义是什么?_C++_Constants - Fatal编程技术网

C++ 常量正确性的定义是什么?

C++ 常量正确性的定义是什么?,c++,constants,C++,Constants,我认为“const correction”的概念定义得很好,但当我与其他人谈论它时,似乎我们对它的含义有不同的看法。有人说这是关于一个程序在尽可能多的地方有“const”注释。其他人将程序定义为const correct,当且仅当使用const注释的地方不存在违反constness的情况(即编译器为您检查的属性) 我想知道这些函数中哪一个是常量正确的: struct Person { string getName1() const { return _name; } string

我认为“const correction”的概念定义得很好,但当我与其他人谈论它时,似乎我们对它的含义有不同的看法。有人说这是关于一个程序在尽可能多的地方有“const”注释。其他人将程序定义为const correct,当且仅当使用const注释的地方不存在违反constness的情况(即编译器为您检查的属性)

我想知道这些函数中哪一个是常量正确的:

struct Person {
    string getName1() const { return _name; }
    string getName2() { return _name; }
    string getName3() const { _name = "John"; return _name; }
    string getName4() { _name = "John"; return _name; }

    string _name;
};
我在互联网上搜索过定义,但找不到确切的答案,而且我还怀疑可能有一个案例在起作用。那么,有人能为一个定义提供可靠的引证吗?

在我看来,“const correction”是指:

所有不打算修改的内容都应标记为
const

这意味着编译器可以在您出错时告诉您。(在某些情况下,这也可能对优化产生影响,但这更多是次要的好处,取决于许多其他因素)

这有三个基本的用途:

  • 成员函数可以标记为
    const
    ,如示例所示。这意味着您从该函数中访问成员变量就好像变量本身是
    const
    。(这是您展示的示例,尽管
    getName3()
    不起作用)

  • “自由”变量、局部变量和成员变量本身也可以标记为
    const
    ——一旦初始化,它们可能不会更改。示例-局部变量:

    int f(int i) {
       const int square = i*i;
       // do something here that uses, but doesn't change square
       return square;
    }
    
    extern const double PI; // set somewhere else but not changed.
    
    class foo {
       const int state; // can't be changed once constructed
       foo(int s) : state(i) {}
    };
    
    或自由变量:

    int f(int i) {
       const int square = i*i;
       // do something here that uses, but doesn't change square
       return square;
    }
    
    extern const double PI; // set somewhere else but not changed.
    
    class foo {
       const int state; // can't be changed once constructed
       foo(int s) : state(i) {}
    };
    
    或成员变量:

    int f(int i) {
       const int square = i*i;
       // do something here that uses, but doesn't change square
       return square;
    }
    
    extern const double PI; // set somewhere else but not changed.
    
    class foo {
       const int state; // can't be changed once constructed
       foo(int s) : state(i) {}
    };
    
  • 函数参数也可以标记为
    const
    ,定义仍然可以匹配非const声明:

    void f(int i);
    void f(const int i) {
        // the fact that i is const is an implementation detail of f here
    }
    
    作为旁注,在某些情况下,参考的正确性是必需的:

    void g(const std::string& s);
    void f(std::string& s);
    
    这两种方法中的一种可以在更多的地方使用:

    g("hi"); // Fine
    f("hi"); // Not fine - you can't bind a temporary to a reference
    
    当然,如果您想更改
    s
    ,那么传入一个临时值就没有什么意义了

  • 只讨论C++的const正确性。引用它:

    这意味着使用关键字const来防止const对象 变异了

    关于您的会员职能:

    string getName1() const { return _name; }
    
    这一点是正确的。它只返回成员变量的副本

    string getName2() { return _name; }
    
    这一个不是const-correct,因为它未声明为const-member

    string getName3() const { _name = "John"; return _name; }
    
    常量不正确,因为它修改常量成员函数中的成员变量。它应该会产生编译错误

    string getName4() { _name = "John"; return _name; }
    
    它是常量正确的,因为它修改了一个成员变量。

    文本来自:

    string getName2() { return _name; }
    
    这意味着使用关键字const来防止const对象 变异了


    Const correction是正确识别和指定方法可变或不可变的情况

    任何不可变的都应该标记为const


    阅读更多关于的信息,仅
    getName3
    违反常量正确性,因为
    \u name
    在函数体中是常量(具体来说,它是
    const std::string&
    ),而
    std::string::operator=
    不是
    const

    getName2
    是一个糟糕的设计,因为它需要一个可变的上下文,即使它不执行任何突变,所以它应该被声明为
    const
    ,否则会导致意外的限制,即不能通过
    const Person&
    调用它

    您还可以将“volatile”和“rvalue”正确性添加到混合中,它们在精神上是相似的

    常数的正确性可以通过其非局部效应来感受。典型的例子是关系运算符(
    operatorgetName3()不正确,因为它更改了名称。其他的都是正确的


    指定方法常量有时是不必要的,有时也是必需的。当我完成项目编码后,我会检查哪些方法可以设置为常量,以提高代码的可读性。虽然仍在编码,但我没有经常指定方法常量,因为这会阻碍工作的进行。出于同样的原因,我声明所有成员在我完成编码之前,它是公共的,然后我在任何适用的情况下应用私有和受保护的。

    getName3不会编译,所以跳过它。各位,请注意问题的最后一部分,关于提供可靠的源代码。有些人的网页在我心目中并不重要(即使是Marshall Cline)@ ExcLyy:Marshall Cline的网站并不仅仅是C++爱好者的网站,它拥有官方的C++ FAQ,由代码> Cop.Lang.C+的正则函数组装。如果你想知道C++的一些地方,你可以找到可靠的来源,你可以找到你书架上的书的作者(包括但不限于Bjarne Stroustrup)回答你的问题。