C++类中const的用法

C++ 类中的const用法总结:

先看一个例子:

class A

{

public:

  A(int x) : num(x), b(x) {}

  void fun(const A& a);  //const修饰函数形参

  int GetNum(void) const;//const修饰不修改成员变量的函数

  void SetNum(int x);

  A& operator=(const A& other);  //const修改成员函数的返回值和形式参数

  const A operator*(const A& left, const A& right);            //const 修改成员函数的返回值

private:

  int num;        //普通成员

  const int b;     //const成员

  static int c;     //静态成员

  static const int d;  //静态常量成员

};

int A :: c = 0;

const int A :: d = 0;

int A :: GetNum(void) const

{

  return num;

}

void A :: SetNum(int x)

{

   num +=1;

}

const A A :: operator*(const A& left, const A& right)

{

  return A(left.num*right.num);

}

一、 const成员变量

1. const 成员的初始化: 不能在定义处初始化,只能在构造函数列表中初始化,而且必须要有构造函数

原因:const数据成员只在某个对象生存期内饰常量,而对于整个类而言确实可变的。

     因为类可以创建多个对象,不同的对象其const数据成员的值可以不同。

     所以不能在类声明中初始化const数据成员,因为类的对象未被创建时,编译器不知道const数据成员的值是什么。

2. static 的const 成员的初始化 遵循static的初始化规则,在类定义的外边初始化

     要想建立在整个类中都恒定的常量,应该用类中的枚举常量来实现,或者static const。

二、const成员函数

1. const修饰类的成员函数的形参

  void fun(const A& a);  //(1)

  void fun1(A a);     //(2)

  第二个函数效率低。 函数体内产生A类型的临时对象用于“值传递”参数a,临时对象的构造、复制、析构过程都将消耗时间

  而第一个函数提高了效率,用“引用传递”不需要产生临时对象,省了临时对象的构造、复制、析构过程消耗的时间;

  但只要引用有可能改变a,所以加const。

总结:

(1) 参数const通常用于参数为指针或引用的情况,且只能修饰输入参数,保护其内容不被修改;

  若输入参数采用“值传递”方式,由于函数将自动产生临时变量用于复制该参数,该参数本就不需要保护,所以不用cosnt。

(2) 对于非内部数据类型的输入参数,应该将“值传递”的方式改为“const 引用传递”,目的是为了提高效率;

(3) 对于内部数据类型的输入参数,不要将"值传递“的方式改为”const 引用传递“。否则即达不到提高效率的目的,又降低了  函数的可理解性、如

  void Func(int x) 不应该改为:void Func(const int& x)

2. const修饰类的成员函数

  int GetNum(void) const;  //(1)

  void SetNum(int x);    //(2)

  一些成员函数改变对象,如(2),一些成员函数不改变对象,也即不修改对象的数据成员,如(1)。

  为了使成员函数的意义更加清楚,我们可在不改变对象的成员函数的函数原型中加上const 说明。

(1)任何不需要修改数据成员的函数都应该使用const修饰

      这样即使不小心修改了数据成员或者调用了非const成员函数,编译器也会报错;

(2)const成员函数应该在函数原型声明和定义中都增加const限定,否则编译器会把它们看成是不同的函数

(3)const对象只能调用 由const显示修饰的const成员函数,不能调用该类的非const成员函数, 因为它可能企图修改常量的数据成员

例如:

const A a(1);

A.GetNum();  //right

A.SetNum();  //error

  但构造函数和析构函数对这个规则例外,他们从不定义为常量成员,但是可被常量对象调用。

(4)const成员函数的作用

   提高程序的可读性;(const成员函数不修改数据成员的值;非const成员函数修改)

   提高程序的可靠性;(如果在const成员函数中修改数据成员的值,编译器按错误处理)

(5)定义const成员函数时,把const关键字放在函数的参数表和函数体之间。

    为什么不放在函数声明前呢?->这样意味着函数的返回值是常量,意义完全不同。

3. const 修改成员函数的返回值

  const A operator*(const A& left, const A& right);  

  这样声明了返回值,起到了保护作用。防止如下情况发生:

  A a(1), b(2), c(3);

  (a * b) = c;

总结:

(1) 一般用const 修饰返回值为对象本身(非引用或指针)的情况多用于二目操作符重载函数并产生新对象的时候;

  但是通常不建议:用const修饰函数的返回值类型为某个对象或者某个对象引用的情况。

原因:如果返回值为某个对象,为const,(const A test =  A 实例)或某个对象的引用为const(const A& test = A实例)

则返回值是const属性, 则返回实例只能访问A中的共有(保护)数据成员和const成员函数,并且不允许对其进行赋值操作,这在一般情况下很少用到

(2) 如果给采用 ”指针传递“方式的函数返回值加const修饰,那么函数返回值(即指针)的内容不能被修改,则该返回值只能被赋给加const修饰的同类型指针。

如: const char * GetString(void);

   char *str = GetString();  //error

   const char* str = GetString();  //right

(3) 函数返回值采用”引用传递”的场合不多,一般只出现在类的赋值函数侯中,目的是为了实现链式表达:

A& operator=(const A& other);

A a,b ,c;

a = b =c;  //right

(a = b) = c;  //error

(4) const A& operator=(const A& a);这样可以么

(5) 不要轻易的将函数的返回值类型定位const

(6) 除了重载操作符外一般不要将返回值类型定为某个对象的const引用

Reference:

1. http://www.cnblogs.com/BloodAndBone/archive/2011/04/12/2013280.html

2. http://www.cnblogs.com/goodloop/archive/2010/04/13/1711368.html

时间: 2025-01-20 06:04:45

C++类中const的用法的相关文章

C++类中const一些用法

在类中的const基本有三种用法 const int func(); // 返回值是const类型 int func(const int); // 参数为const类型 int func(int )const; // 为const类型的成员函数,只能调用类中const类型的变量: 另外,当类的实例是const类型时,也只能调用类中的const成员函数,且只有类的成员函数才能被修饰为const类型: //Point.h #include <iostream> using namespace st

C#类中static变量用法分析

本文实例讲述了C#类中static变量用法.分享给大家供大家参考.具体分析如下: 先来看一段代码: 代码如下: using System; namespace Param { class Class1 { static int i = getNum(); int j = getNum(); static int num = 1; static int getNum() { return num; } [STAThread] static void Main(string[] args) { Co

C/C++中const的用法

const是C语言的关键字,经C++进行扩充,变得功能强大,用法复杂.const用于定义一个常变量(只读变量),当const与指针,引用,函数等结合起来使用时,情况会变得复杂的多.下面将从五个方面总结const的用法. 1.const位置 const位置较为灵活,一般来说,除了修饰一个类的成员函数外,const不会出现先一条语句的最后.示例如下: #include <iostream> using namespace std; int main(int argc,char* argv[]) {

C++中const关键字用法

为什么使用const?采用符号常量写出的代码更容易维护:指针常常是边读边移动,而不是边写边移动:许多函数参数是只读不写的.const最常见用途是作为数组的界和switch分情况标号(也可以用枚举符代替),分类如下: 常变量:  const 类型说明符 变量名 常引用:  const 类型说明符 &引用名 常对象:  类名 const 对象名 常成员函数:  类名::fun(形参) const 常数组:  类型说明符 const 数组名[大小] 常指针:  const 类型说明符* 指针名 ,类型

C++中const的用法

1.const修饰普通变量和指针 (1).const修饰普通变量 其写法有2种:a.const type value;   b.type const value; 这两种写法本质上是一样的.其含义是:const修饰的类型为type的变量value是不可变的. (2).const修饰指针 A.const char * value; B.char * const value; C.char const * value; D.const char* const value; 对于前3种,我们换种方式,

如何牢记C/C++中const的用法?

(下面以 typename 表示C/C++内某一类型 我常常会搞混 const 放在 typename* 的前面和后面的区别,今天特地查看了它们两个各自的含义,总结了一下: const typename* ptr 是指 ptr 是个指向常量的指针( pointer to constant data ),它认定所指向的内容是个常量,因此不能通过 *ptr 来改变它所指向的内容.比如说: 1 const int apple = 0; 2 const int* thirstyBoy = &apple;

ES6中const的用法

const声明一个只读的常量.一旦声明,常量的值就不能改变.且const一旦声明变量,就必须立即初始化,不能留到以后赋值. const的作用域与let命令相同:只在声明所在的块级作用域内有效. const命令声明的常量也是不提升,同样存在暂时性死区,只能在声明的位置后面使用.也与let一样不可重复声明. const实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址不得改动. const如果引用的是一个对象,只能保证引用对象的这个指针不变,但对象本身的数据结构是可以改变的.如: co

C与C++中const区别

一.C中的const,功能比较单一,较容易理解. · 作用      : 被修饰的内容不可更改. · 使用场合: 修饰变量,函数参数,返回值等.(c++中应用场合要丰富的多) · 特点      : 是运行时const,因此不能取代#define用于成为数组长度等需要编译时常量的情况.同时因为是运行时const,可以只定义而不初始化,而在运行时初始化.如 const int iConst;. 另外,在c中,const变量默认是外部链接,因此在不同的编译单元中如果有同名const变量,会引发命名冲

类内const static(static const)成员变量初始化问题

在查找const相关资料的过程中,又遇到了另外一个问题,就是C++类中const static(或者static const)成员变量应当如何初始化的问题. 查阅了许多资料,发现VC环境下,只允许const static成员变量在类外初始化,这个应该是编译器遗留下的bug(你也可以说是要求严格). 在其他编译器下,整型以及枚举类型的const static成员变量是允许在声明的同时进行初始的,其中整型包括int.short.long.char等,非整型是指浮点型 包括float.double等.