• C++:const pointer to an object [指向一个对象的const 指针变量]


    0 引言

    const is widely used in C++, this blog will record common usage of const. Including:

    1. const values(number variable, string variable, stl variable, ...), const value 是一个值,可以正常用于拷贝,初始化其他变量等,仅仅在执行改变该const val的时候才会触发作用。由于const值不能被改变,因此标准中规定必须要对const value进行初始化。 一般有两种方法对const值进行初始化:
      • 声明时初始化
      • 函数中声明为const的形参在函数被调用时会得到参数值
    2. pointer to const value(指向常量的指针), 不能用于改变其所指对象的值。要想存放常量对象的地址,只能使用指向常量的指针。 low-level const, pointer can be changed but not variable it pointed.
      • const double pi = 3.14;   const double *ptr = &pi;     ///< 意为解引用ptr (*ptr) 会得到一个const double的value.
    3. const pointer to value, 必须初始化,而且一旦初始化完成,则它的值(即地址)就不能再改变了。 top-level point, pointer cannot be changed but not variable.
      • int errNumb = 0;  int *const curErr = &errNum;      ///< 意为解引用const curErr(*curErr) 得到一个可变的int值,但指针本身的值不能变化。
    4. const pointer to const value
      • int const  *const cpci;  ///< both pointer and the value it pointer is const.

     reference:

    Microsoft Dos: https://docs.microsoft.com/en-us/cpp/cpp/const-cpp?view=msvc-160

    const error: https://stackoverflow.com/questions/26963510/error-passing-const-as-this-argument-of-discards-qualifiers

    C和指针》

    1 example of top && low level pointer && const reference 

    1.1 const pointer to value: 表示指针本身是一个常量, 可以调用class member function 对 class member var进行修改

    这种形式可以调用class member function,并且允许改变class member var 的值, 但是不能改变指针本身的值(即地址)

    demo:

    #include <iostream>
    
    class Var {
    public:
        Var(const int *a) {}
        Var(const int &size) {
            d_size = size;
        }
        int getSize() const { return d_size; }  ///< https://stackoverflow.com/questions/3141087/what-is-meant-with-const-at-end-of-function-declaration
    ///< is equal as int getSize(const Var *this){resutn d_size}, which means that getSize is not allowed to change value by a const this pointer.
    void setSize(const int &size) { d_size = size; } private: int d_size; }; void TestConstRef() { Var aa(77); Var *const tempVar = &aa; ///< 解引用const tempVar得到一个可变的Var object,可以通过tempVar引用Var的函数对aa对象进行修改 std::cout << "aa.size = " << tempVar->getSize() << std::endl; tempVar->setSize(89); std::cout << "aa.size = " << tempVar->getSize() << std::endl; } int main(){ TestConstRef(); return 0; }

    result

    Output:
    aa.size = 77 aa.size = 89

    1.2 pointer to const: 指针本身不是一个常量,指针指向的对象是一个常量

    这种形式只能调用被const限定的 (at the end of declaration) class member function。 不能修改指针指向的对象的class member var.

    demo

    #include <iostream>
    
    class Var {
    public:
        Var(const int &size) { d_size = size; }
        int getSize()const { return d_size; }
        void setSize(const int &size) { d_size = size; }
    
    private:
        int d_size;
    };
    
    void ChangeSize(const Var *aa) { ///< aa is a pointer to a const, aa itself can be changed, but var it pointed can not be changed.
        aa->setSize(89);             ///< equal as setSize(const Var *this, const int &size) {d_size = size}, now that aa is a pointer to a const this pointer, setSize is not allowed to change value of aa.
        std::cout << "aa.size = " << aa->getSize() << std::endl;
    }
    
    void TestConstRef()
    {
        Var aa(77);
        std::cout << "aa.size = " << aa.getSize() << std::endl;
        ChangeSize(&aa);
    }
    
    int main(){
        TestConstRef();
        return 0;
    }

    result: not supported to pass pointer to const when you need to change content of var it pointed.

    Compile error:
    const_test.cpp: In function ‘void ChangeSize(const Var*)’: const_test.cpp:16:19: error: passing ‘const Var’ asthis’ argument of ‘void Var::setSize(const int&)’ discards qualifiers [-fpermissive] aa->setSize(89);

    1.3 const reference

    如果确定了调用的class member function不会对class member var进行赋值、更改的话,就应该用这种形式。

    demo:

    #include <iostream>
    
    class Var {
    public:
        Var(const int &size) { d_size = size; }
        int getSize()const { return d_size; } ///< function called by const reference object should be limited by const at the end, or it will report an error like
                                               ///< "error: passing ‘const Var’ as ‘this’ argument of ‘int Var::getSize()’ discards qualifiers [-fpermissive]" 
       void setSize(const int& size) { d_size = size; }
    private:
        int d_size;
    };
    
    void noChangeSize(const Var &aa) {
        aa.setSize(89); ///< not supported. first run:
        std::cout << "aa.size = " << aa.getSize() << std::endl;  ///< second run
    }
    
    void TestConstRef()
    {
        Var aa(77);
        std::cout << "aa.size = " << aa.getSize() << std::endl;
        noChangeSize(aa);
    }
    
    int main(){
        TestConstRef();
        return 0;
    }

    result

    first run output:

      test.cpp: In function ‘void noChangeSize(const Var&)’:
      test.cpp:14:18: error: passing ‘const Var’ as ‘this’ argument of ‘void Var::setSize(const int&)’ discards qualifiers [-fpermissive]
      aa.setSize(89); ///< not supported.

    second run output

    aa.size = 77
    aa.size = 77

    2 summary

    • 1.1 is not commonly used, 1.2 and 1.3 is commonly used to protect val pointed by pointer.
    • 1.1 can be replaced by pointer itself, which is more common.
    • 1.3 is the most safe usage. If you can choose to use const reference, do not hesitate.
  • 相关阅读:
    设计实现业务系统中的用户权限管理
    海量数据的存储和访问解决方案
    Windows2003 IIS6.0配置主机头,一机多站
    web.config(2)
    web.config(1)
    如何查看windows下哪些端口被哪些进程正在监听
    net开发人员应该知道
    异步与多线程的区别(异步是目的,多线程是实现它的一种方式,异步的优先级有时候比主线程还高)
    如何检查Android网络连接状态
    android WIFI检测与设置
  • 原文地址:https://www.cnblogs.com/ghjnwk/p/15555186.html
Copyright © 2020-2023  润新知