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.

 

posted @ 2021-11-15 11:03  十步一杀2017  阅读(224)  评论(0编辑  收藏  举报