Const_C++

Const c++的使用总结

1
2
3
4
5
const std::vector<Hand::Ptr> & HandDetector::getHands() const {

return hands;

}//const函数重载

基本知识

  1. const修饰常量时,定义时必须初始化

对于类中的const成员必须通过初始化列表进行初始化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class A
{
public:
A(int i);
void print();
const int &r;
private:
const int a;
static const int b;
};
const int A::b=10;
A::A(int i):a(i),r(a)
{

}
  1. Const 默认在文件中为局部变量,如果需要在别的文件中访问需要显示的定义为外部变量,非const的变量默认为外部变量
  2. 很有趣的地方:
1
2
3
4
5
6
7
8
9
10
11
#include <iostream>

int main(int argc, const char * argv[]) {
// insert code here...
double a = 3.14;
const int &ri = a;
// Non-const lvalue reference to type 'int' cannot bind to a value of unrelated type 'double'
int &b = a;
std::cout << "Hello, World!\n";
return 0;
}

非const引用只能绑定到与该引用相同类型的对象。 const引用则可以绑定到不同但相关的类型的对象或绑定到右值。

原因在于编译器在编译的时候,对于引用存放的是一个对象的地址,对于不可寻址的值,如文字常量以及不同类型的对象,编译器为了实现引用,必须生成一个临时对象,引用实际上指向该对象,但用户不能访问它。ri是const所以没有办法修改的ri的赋值,但是对于b一旦修改了b的值我们希望同时修改a的值,但是由于编译器其实修改的是临时对象temp的值,而不是a的值,所以会造成误解,所以在编译的时候回报错。

  1. const对象的动态数组
1
2
3
4
const int *temp = new const int[100]();
//const的修饰的数组必须初始化,所以使用这种方式可以zero initial整个数组
const std::string *temp = new std::string[2];//会调用string类的默认构造函数初始化
//c++允许定义类类型的const数组,但是必须提供默认构造函数
  1. 指针和const修饰符

    • 指向const的指针
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      const double *cptr;
      // cptr是一个指向double类型的const对象的指针,cptr可以指向不同的const对象,但是不能通过cptr修改对象的值。
      *ctpn = 42;//错误,不能修改值
      const double pi = 3.14
      double *ptr = $pi; //错误,不能把一个const的对象的地址赋给一个普通的非const指针,因为这样可以修改const的值
      const double *ctpr = &pi;//可以的
      //允许把非const对象的值赋给const对象的指针 但是不能用const对象的指针来修改其值,修改方法需要借助别的非const指针
      double dval = 3.13;
      cptr = &dval;
      double *ptr = &dval;
      *ptr =3.14;
      cout<< *cptr;//结果是3.14 自以为指向const的指针,偷偷修改它也不知道
  • 常指针

    本身的值不能修改,与其他const量一样,需要在定义的时候初始化。

1
2
int a = 0;
int *const ptr = &a;//能不能修改指向对象的值,取决于指向对象本身的类型
  1. 函数和const限定符的关系

    • 类中的const成员函数

      • 在一个类中,任何不会修改数据成员的函数都应该声明为const类型。如果在编写const成员函数时,不慎修改了数据成员,或者调用了其它非const成员函数,编译器将指出错误,这无疑会提高程序的健壮性。使用const关键字进行说明的成员函数,称为常成员函数。只有常成员函数才有资格操作常量或常对象,没有使用const关键字说明的成员函数不能用来操作常对象。常成员函数说明格式如下:

        <类型说明符> <函数名> (<参数表>) const;

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        class tempstack
        {
        private:
        int m_num;
        int m_data[100];
        public:
        void Push(int elem);
        int Pop(void);
        int GetCount(void) const;
        };
        int tempstack::GetCount(void) const
        {
        //++m_num;//编译错误Cannot assign to non-static data member within const member function 'GetCount'
        //Pop();//Member function 'Pop' not viable: 'this' argument has type 'const tempstack', but function is not marked const
        return m_num;
        }
    • 函数重载

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      #include <iostream>
      class R
      {
      public:
      R(int r1,int r2)
      {
      R1 = r1;
      R2 = r2;
      }
      void print();
      void print() const;
      private:
      int R1,R2;
      };
      void R::print()
      {
      std::cout<<R1;
      }
      void R::print() const
      {
      std::cout<<R2;
      }

      int main(int argc, const char * argv[]) {
      R a(1,2);
      a.print();//1
      const R b(3,4);
      b.print();//4
      return 0;
      }

      const 对象默认调用const成员函数