C++ Const的使用2



C++_Const的使用(2),3、与类有关的const

1)const修饰成员变量:成员常量不能被修改初始化:

方法一:只能在构造函数的初始化列表中赋值—-比较常用

 
  1. class A
  2. {
  3. private:
  4.     const int n;   //成员常量不能被修改
  5. public:
  6.     A(int x): n(x) //只能在初始化列表中赋值
  7.     { } ;
  8. }

方法二:把变量static 和 const 并用,在外部初始化

[cpp] view plaincopy

  1. class A
  2. {
  3. public:
  4.     A()
  5.     {}
  6. private:
  7.     static const int i; //注意必须是静态的!
  8. };
  9. const int A::i=3;

注意:为什么const成员不能在构造函数体中进行初始化?

原因:在构造函数中那叫赋值,因为定义在类中已经定义好了,之后只需要在构造函数赋值就可以了,这是定义和赋值时分开的。但是,const变量是必须在定义的时候初始

的,因此只能使用初始化列表中进行,表示是在定义时就能初始化。

2)const修饰成员函数:常函数,函数体为常量,不能改变其他非const成员的值

使用时间:任何不会修改数据成员(即函数中的变量)的函数都应该声明为const 类型

const位置:一般写在函数的尾部来const修饰的成员函数

主要作用:只能被const类对象、指针、引用调用

[cpp] view plaincopy

  1. class A
  2. {
  3.     void function()const; //常成员函数, 它不改变对象的成员变量. 也不能调用类中任何非const成员函数。
  4. }

说明:

注意一:在const成员函数内部不允许修改数据成员。反过来,将修改数据成员的成员函数声明为const将导致编译错误。

注意二:const成员函数不允许调用非const成员函数,而只能使用const成员。

非const成员函数可以调用const成员函数。

注意三:可以对const成员函数进行非const版本的重载。

注意四:构造函数和析构函数不允许声明为const类型。构造函数既可以初始化const对象,也可以初始化非const对象。析构函数同理。

注意五:建议将不修改数据成员的成员函数都声明为const。当编写这种成员函数时,若不经意修改了数据成员,编译器将产生错误信息。

代码:

const重载

[cpp] view plaincopy


  1. #include<iostream>
  2. using namespace std;
  3. class A
  4. {
  5. private:
  6.     int a;
  7.     const int b;
  8. public:
  9.     A(int i,int j):b(j)
  10.     {
  11.         a=i;
  12.     }
  13.     void print()
  14.     {
  15.         cout<<”非const函数”<<endl;
  16.         cout<<a<<b<<endl;
  17.     }
  18.     void print ()const
  19.     {
  20.         cout<<”const函数”<<endl;
  21.         cout<<a<<b<<endl;
  22.     }
  23. };
  24. void main()
  25. {
  26.     A a(1,2);
  27.     a.print(); //a为普通的对象,会调用普通的成员函数
  28.     const A aa(3,4);
  29.     aa.print();//aa为常对象,会调用常成员函数
  30.     system(“pause”);
  31. }

注意四:同一成员函数名,若只有const型,则非const对象可以调用该成员函数,即调用const成员函数。 <见上面的例子const重载>

注意五:同一成员函数名,若既有非const型,又有const型(重载),则非const对象只调用非const成员函数。<见上面的例子const重载>

常对象和常成员函数的调用

[cpp] view plaincopy

  1. #include<iostream>
  2. using namespace std;
  3. class A
  4. {
  5. private:
  6.     int a;
  7.     const int b;
  8. public:
  9.     A(int i,int j):b(j)
  10.     {
  11.         a=i;
  12.     }
  13.     void print ()const
  14.     {
  15. //      a=10;//错误,常函数中不能更新数据成员
  16.         cout<<”const函数”<<endl;
  17.         cout<<a<<b<<endl;
  18.     }
  19.     void set(int i,int j)
  20.     {
  21.         a=i;
  22. //      b=j;//错误,const成员不能改变
  23.     }
  24. };
  25. void main()
  26. {
  27.     const A a(3,4);
  28. //  a.set(5,6);//错误,常对象不能调用非常成员,常成员函数是常对象唯一对外出口
  29.     a.print(); //正确,常对象只能调用常函数。
  30.     system(“pause”);
  31. }

 

3)const修饰类对象、对象指针、对象引用:常量对象(对象指针和对象引用),任何成员都不能被修改,只能调用常成员函数。

注意一:const对象在定义后,其值不可被改变。

注意二:const对象不允许进行成员函数的调用,即使是不修改对象的成员函数也不行。除非成员函数本身也声明为const。

即:const对象只可调用const成员函数,不能调用任何非const成员函数(构造与析构函数除外)。

原因:任何非const成员函数会有修改成员变量的企图。

注意三:非const对象既可调用const成员函数,可调用非const成员函数。

注意四:同一成员函数名,若只有const型,则非const对象可以调用该成员函数,即调用const成员函数。 <见上面的例子const重载>

注意五:同一成员函数名,若既有非const型,又有const型(重载),则非const对象只调用非const成员函数。<见上面的例子const重载>

[cpp] view plaincopy

  1. class A
  2. {
  3.     void func1();
  4.     void func2() const;
  5. }
  6. const A aObj;
  7. aObj.func1(); //错误,常函数只能调用常成员函数
  8. aObj.func2(); 正确
  9. const A* aObj = new A();
  10. aObj-> func1();//错误,常指针只能调用常成员函数
  11. aObj-> func2(); 正确

注意:
1、const对象只能访问const成员函数, 非const对象可以访问任意的成员函数=const成员函数+非const成员函数.

2、const对象的成员是不可修改的,然而const对象通过指针维护的对象却是可以修改的.

3、常量指针被转化成非常量指针,并且仍然指向原来的对象;

常量引用被转换成非常量引用,并且仍然指向原来的对象;

常量对象被转换成非常量对象

4、将Const类型转化为非Const类型的方法 :略

const使用建议:

1、在参数中使用const应该使用引用或指针,而不是一般的对象实例;

2、const在成员函数中的三种用法(参数、返回值、函数)要很好的使用

1)参数:const A& a:只要函数体内是只读,不会修改参数,又想提高效率,则常常使用const &

2)返回值:不要轻易的将函数的返回值类型定为const,除了重载操作符外一般不要将返回值类型定为对某个对象的const引用;

3)常函数:任何不会修改数据成员的函数都应该声明为const 类型。