1.在一个函数声明中,const 可以修饰函数的返回值,或某个参数;对于成员函数,还可以修饰是整个函数。有如下几种情况,以下会逐渐的说明用法:

A& operator=(const A& a);
                void fun0(const A* a );
                void fun1( ) const; // fun1( ) 为类成员函数
                const A fun2( );

1) 修饰参数的const,如 void fun0(const A* a ); void fun1(const A& a);

调用函数的时候,用相应的变量初始化const常量,则在函数体中,按照const所修饰的部分进行常量化,如形参为const A* a,则不能对传递进来的指针的内容进行改变,保护了原指针所指向的内容;如形参为const A& a,则不能对传递进来的引用对象进行改变,保护了原对象的属性。

[注意]:

参数const通常用于参数为指针或引用的情况,且只能修饰输入参数;若输入参数采用“值传递”方式,由于函数将自动产生临时变量用于复制该参数,该参数本就不需要保护,所以不用const修饰。

[总结]:

对于非内部数据类型的输入参数,因该将“值传递”的方式改为“const引用传递”,目的是为了提高效率。例如,将void Func(A a)改为void Func(const A &a)

对于内部数据类型的输入参数,不要将“值传递”的方式改为“const引用传递”。否则既达不到提高效率的目的,又降低了函数的可理解性。例如void Func(int x)不应该改为void Func(const int &x)

2) 修饰返回值的const,如const A fun2( ); const A* fun3( );

这样声明了返回值后,const按照"修饰原则"进行修饰,起到相应的保护作用。const Rational operator*(const Rational& lhs, const Rational& rhs)

{
        return Rational(lhs.numerator() * rhs.numerator(),
        lhs.denominator() * rhs.denominator());
        }

返回值用const修饰可以防止允许这样的操作发生:Rational a,b;

Radional c;
        (a*b) = c;

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

[总结]:

(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();
                  正确的用法是:
                  const char *str=GetString();

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

class A
                  {…
                  A &operate = (const A &other); //赋值函数
                  }
                  A a,b,c; //a,b,c为A的对象
                  …
                  a=b=c; //正常
                  (a=b)=c; //不正常,但是合法

若赋值函数的返回值加const修饰,那么该返回值的内容不允许修改,上例中a=b=c依然正确。(a=b)=c就不正确了。

[思考3]: 这样定义赋值操作符重载函数可以吗?

const A& operator=(const A& a);

2. 类成员函数中const的使用

一般放在函数体后,形如:void fun() const;

任何不会修改数据成员的函数都因该声明为const类型。如果在编写const成员函数时,不慎修改了数据成员,或者调用了其他非const成员函数,编译器将报错,这大大提高了程序的健壮性。如:

class Stack
        {
        public:
                void Push(int elem);
                int Pop(void);
                int GetCount(void) const; //const 成员函数
        private:
                int m_num;
                int m_data[100];
        };
        int Stack::GetCount(void) const
        {
                ++m_num; //编译错误,企图修改数据成员m_num
                Pop(); //编译错误,企图调用非const函数
                Return m_num;
        }

3. 使用const的一些建议

(1)要大胆的使用const,这将给你带来无尽的益处,但前提是你必须搞清楚原委;
            (2)要避免最一般的赋值操作错误,如将const变量赋值,具体可见思考题;
            (3)在参数中使用const应该使用引用或指针,而不是一般的对象实例,原因同上;
            (4) const在成员函数中的三种用法(参数、返回值、函数)要很好的使用;
            (5) 不要轻易的将函数的返回值类型定为const;
            (6)除了重载操作符外一般不要将返回值类型定为对某个对象的const引用;

转载于:https://www.cnblogs.com/MarvinGeng/archive/2012/07/16/2593262.html

const在函数声明中的应用(转)相关推荐

  1. C语言封装带省略参数的函数,C与C++的函数声明中省略参数的不同意义

    一直都以为C/C++中形如 int func(); 这样的函数声明其意义就是一个参数 void(没有参数)的函数.然而今天在看C++的时候突然看到这么一句: 对于带空参数表的函数,C和C++有很大的不 ...

  2. python 定义函数参数的类型_1作为函数声明中的参数类型 - python

    如果在我的示例中需要在Python数组中指定参数类型,则需要编写如下内容: def my_function(param: list): pass 在Swift中,您可以这样指定参数类型: func m ...

  3. JavaScript 中的 Hoisting (变量提升和函数声明提升)

    如何将 函数声明 / 变量 "移动" 到作用域的顶部. 术语 Hoisting(提升) 在很多 JavaScript 博文中被用来解释标识符的解析.其实 Hoisting(提升) ...

  4. const在函数前与函数后的区别 [转]

    [转] http://blog.csdn.net/clozxy/article/details/5679887 一   const基础           如果const关键字不涉及到指针,我们很好理 ...

  5. Item 16: 让const成员函数做到线程安全

    本文翻译自modern effective C++,由于水平有限,故无法保证翻译完全正确,欢迎指出错误.谢谢! 博客已经迁移到这里啦 如果我们在数学领域里工作,我们可能会发现用一个类来表示多项式会很方 ...

  6. html绑定带有形参的函数,C++中函数

    参数 参数分为形参和实参,形参是在函数定义的形参表中进行定义,是一个变量,其作用域为整个函数.而实参出现在函数调用中,是一个表达式,用传递给函数的实参对形参进行初始化. 函数形参表可以为空,但不能省略 ...

  7. C语言正函数nosign,Function declarations(函数声明)

    函数声明引入了一个指定函数的标识符,并且可选地指定函数参数的类型(原型).函数声明(与定义不同)可能出现在块作用域和文件作用域中. 句法 在函数声明的声明语法中,可能由声明者修改的类型说明符序列指定返 ...

  8. Python函数参数中的冒号与箭头

    在一些Python的工程项目中,我们会看到函数参数中会有冒号,有的函数后面会跟着一个箭头,你可能会疑惑,这些都是什么东西? 其实函数参数中的冒号是参数的类型建议符,告诉程序员希望传入的实参的类型.函数 ...

  9. c语言常用的格式声明,c语言函数声明格式是什么

    c语言函数声明格式是什么 c语言函数声明格式是"函数类型 函数名称(参数列表);".在函数声明中的参数列表中,不需要给出具体的变量名称,但必须给出每个变量的类型. 函数声明,不是说 ...

最新文章

  1. 【转】Itween 贝塞尔曲线(一)
  2. spring mvc 的各种参数的绑定方式
  3. Boost : to_string_stub用法的测试程序
  4. java虚拟机 山寨机_十年前的山寨机居然有系统?没错,还是纯国产的
  5. java基础—采用递归的方式来获取相关目录下的子目录的名称
  6. [转载]对称加密DES和TripleDES
  7. matlab 2017安装教程
  8. 辐射校正(传感器定标+大气校正)
  9. Spring5全面详解
  10. 理正深基坑弹性计算方法_理正深基坑整体计算与单元计算的区别
  11. 关于统计分析软件Spss统计个案数和实际数据的个案数不一致问题
  12. 末日的传说 洛谷p1338
  13. ubuntu mysql-admin_ubuntu 14.04中安装phpadmin即mysql图形管理界面
  14. KF、EKF、IEKF、UKF卡尔曼滤波器
  15. 【php】PHP语言进阶
  16. Ensemble Average(系综平均)(集平均)
  17. 压力应力测试软件,管道强度和应力计算软件
  18. 阿里巴巴直播内容风险防控中的AI力量
  19. 能量原理和变分法笔记1:变分法简介
  20. 方知截教有鸿蒙,“没有三把神沙,不敢倒反西歧”de 来历

热门文章

  1. SAP MM ME1M 报表的Layout之调整
  2. requests抓取以及Xpath解析
  3. latex中\begin{verbatim}以及\verb有什么用?
  4. 器官复刻、脑机接口、电子皮肤…这些前沿科学或改写人类未来
  5. 震撼三观:从细胞到宇宙
  6. 3位物理学家获基础物理学特别突破奖
  7. 5G时代,智能工厂迎来4大改变!
  8. 产业|中国电子学会发布《机器人十大新兴应用领域(2018-2019年)》
  9. Gartner:预计2018年人工智能行业总价值达1.2万亿美元
  10. 年增长率超50%,AI芯片竞争白热化