search

Home  >  Q&A  >  body text

c++11 - const的一些问题(c++primer 第五版)

1.

中文版:

设置一个类型为auto的引用时,初始值中的顶层常量属性依然保留。和往常一样,如果我们给初始值绑定一个引用,则此时的常量就不是顶层常量了。”

英文版:

When we ask for a reference to an auto-deduced type, top-level consts in the initializer are not ignored. As usual, consts are not top-level when we bind a reference to an initializer

怎么理解这段话呢?能否举例说明?

阿神阿神2809 days ago772

reply all(2)I'll reply

  • 天蓬老师

    天蓬老师2017-04-17 11:48:52

    top-level const : const modifies itself.
    low-level const : const modifies someone else .

    What is oneself and what is others? In the world of C++:

    • POD, class object can only be "self"
    • The pointer can be itself (the pointer itself), or it can be someone else (pointing to someone else).
    • QuoteIt doesn’t have itself, it can only be others. (The quote is an alias)

    So, there are the following rules:

      The
    • pointer can be top-level const or low-level const.
    • References can only be low-level const.
    When is the

    pointer top-level const and when is it low-level const? Please refer to your other question answered yesterday.
    (const char * is low-level, char * const is top-level.)


    If you understand the above concepts, let’s understand what you quoted. Example:

    cppconst int ci = 0;
    auto &r1 = ci; // r1 is a const int&
    

    Okay, ci is const int, which is top-level const; what about r1? It's const int&, it's a reference, and the reference must be low-level const.

    So:

    consts are not top-level when we bind a reference to an initializer

    Do you agree with the second part?

    Look at r1 in the example. Can you modify it? You may be confused, nonsense, even after adding const, can it still be modified?

    Let’s look at another example:

    cppconst char * ch = "test";
    ch = "mood"; // ok, const is low-level
    
    char c[4] = "hel";
    char * const cch = c;
    cch = ch; // error! const is top-level
    

    See, for pointers, low-level const can be modified! (Corresponding to the concept of starting, the pointer can be "someone else", and someone else is const, which does not affect the pointer pointing to another person)

    Then const int* can be modified, but const int& cannot be modified, which is caused by the concept of reference itself (it cannot be bound again once initialized).
    That is, while the const reference is low-level const, it also has the characteristics of top-level const, that is, "itself" cannot be modified.

    So:

    When we ask for a reference to an auto-deduced type, top-level consts in the initializer are not ignored.

    means "the top-level constant attributes are still retained". Let's understand the meaning of the top-level constant attributes mentioned here.


    In summary, combine the examples I gave. The simplest explanation:

    auto &r1 = ci; What happened?

    1. Reduced from top-level const to low-level const.
    2. The characteristics of
    3. top-level const (which cannot be modified) are still retained.

    Is it clear?

    PS: Why does C++ Primer advocate using more references and less pointers? Because pointers are too flexible. Quoting is easier to control. . .

    reply
    0
  • 大家讲道理

    大家讲道理2017-04-17 11:48:52

    There are many tutorials in this area, so I simply wrote them down. If you don’t understand them correctly, please feel free to correct me.

    #include <iostream>
    using namespace std;
    
    
    class MyObject{
    private:
        int value;
    public:
        MyObject(){
            this->value = 0;
        }
    
        void foo() {
            cout << "none const obj called" << endl;  //证明调用者是一个非const对象
        }
        void foo() const {
            cout << "const obj called" << endl;   //证明调用者是一个const对象
        }
        MyObject (const MyObject & other){
            this->value = other.value;
        }
    };
    
    int main()
    {
       MyObject obj;
       const MyObject constObj = obj;
       obj.foo();  //输出非const foo
       constObj.foo(); //const foo
       cout<< "*******"<<endl;
       auto auto_without_const = constObj; //auto没有加引用的情况下,即使右边的值有const属性,也被去了
       auto_without_const.foo();
       auto & auto_with_const = constObj; //一旦是引用的时候,就保留下来const属性
       auto_with_const.foo();
    
       auto & const_refer_to_none_const = obj; //右值没有const属性,初始化后也没有
       const_refer_to_none_const.foo();
       return 0;
    }
    

    reply
    0
  • Cancelreply