当前位置: 首页 > 编程日记 > 正文

C/C++中constkeyword

 今天在做一个趋势笔试题的时候。才让我有了系统把constkeyword好好总结一下的冲动,由于这个关键词大大小小好多地方都出现过,出现频率很高,而每次仅仅是简短的把答案看了一下,没有真正将其整个使用方法弄透,立即要找工作了。为避免悲剧再次发生,不得不引起我的重视,这才有了这篇博文。
    首先。一看到constkeyword,我们的第一反应就是定义常量。的确。这没有错。const就是constant的缩写嘛,可是其实他的使用方法远不止这些。

接下来我们一一来解说。

    在C程序中,const的使用方法主要有定义常量、修饰函数參数和修饰函数返回值。

而在C++程序中。它除了上述功能外,还能够修饰函数的定义体,定义类中某个成员函数为恒态函数,即不改变类中的数据成员

。对于定义常量的使用方法,这里就不多说了,重点看一下修饰函数參数、修饰函数返回值以及修饰函数的定义体
    0)修饰变量或指针
int ii=0; 
const int i=0;           //i是常量。i不会被改动 
  const int *p1i=&i;        //p1i所指内容是常量。能够不初始化 
int const* p11i = &i; //同上,const在*号左边,作用是一样的。


  int  * const p2i=ⅈ    //p2i是常量。所指内容可改动 
  const int * const p3i=&i; //p3i是常量。所指内容也是常量 
  p1i=ⅈ                 //合法 
  *p2i=100;               //合法
    1)修饰函数參数
    首先假设该參数用于输出,那么不管是採用指针传递还是引用传递,都不能加const修饰。所以const仅仅能用于修饰输入參数。这里又分三种情况:输入參数採用值传递还是指针传递还是引用传递。

    (1)假设採用值传递。因为函数将自己主动产生暂时变量用于复制该參数,该输入參数本来就无需保护,所以不须要加const 修饰。

     比如。对于函数void Func1(int x)。写成void Func1(const int x)一点意义也没有。

同理,对于void Func2(A a)也不须要写成void Func2(const A a),当中A为用户自己定义的对象类型。

    (2)假设採用指针传递,那么加const能够防止函数体内部对该參数进行改变。起到保护作用。
     比如。如果StringCopy函数定义为:void StringCopy(char *strDest, const char *strSrc)。那么,如果函数体试图改变strSrc的内容,编译器将报错。
    (3)假设採用引用传递。
     首先我们来说一下,为什么要引入引用传递这样的方法。原因是:对于非内部数据类型的參数而言,象void Func(A a) 这样声明的函数注定效率比較底。由于函数体内将产生A 类型的暂时对象用于复制參数a,而暂时对象的构造、复制、析构过程都将消耗时间。为了提高效率。能够将函数声明改为void Func(A& a)。这样一来,依据引用传递的定义,仅仅是借用了參数的别名,不须要产生暂时对象。
      可是,这样一来,当函数体中改变了參数a的值后,对应的传递的原始值也会对应改变。所以假设不希望改变原始參数。仅仅须要在前面加上const修饰。这样一来。函数终于定义为void Func(const A& a)。同理,是否应将void Func(int x) 改写为void Func(const int &x),以便提高效率?全然没有必要。由于内部数据类型的參数不存在构造、析构的过程,而复制也很快。“值传递”和“引用传递”的效率差点儿相当。
     总结一下const作为函数输入參数的使用方法:
     (1)对于非内部数据类型的输入參数,应该将“值传递”的方式改为“const 引用传递”,目的是提高效率。

比如将

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


      2)修饰函数的返回值
      依据上面的思路,这里也分三种情况。即值传递、指针传递、引用传递。

      (1)假设函数返回值採用“值传递”方式,因为函数会把返回值拷贝到外部暂时的存储单元中,加const 修饰没有不论什么价值。

     比如,不要把函数int GetInt(void) 写成const int GetInt(void)。

同理不要把函数A GetA(void) 写成const A GetA(void),当中A 为用户自己定义的数据类型。
    (2)假设函数返回值採用“指针传递”方式。那么函数返回值(即指针)的内容不能被改动,该返回值仅仅能被赋给加const 修饰的同类型指针
     比如,定义函数为:const char *GetString(void),那么char *str = GetString()将会出现编译错误。应该写成const char *str = GetString()。

    (3)假设函数返回值是採用“引用传递”方式,它的意义在于能提供啊效率,而这样的方式使用场合并不多。这个时候,一定要搞清楚函数到底是想返回一个对象的“拷贝”还是仅返回“别名”就能够了,否则程序会出错

     比如。对于类的重载赋值函数A & operate = (const A &other),假设不加cons修饰,则定义A a, b, c;(a = b) = c,程序合法。可是假设加上const修饰,即const A & operate = (const A &other)。则程序会报错。


       3)修饰函数的定义体。
       定义const函数。仅仅须要将constkeyword放在函数声明的尾部不论什么不会改动类的数据成员的函数都应该声明为const 类型

假设在编写

const 成员函数时,不慎改动了数据成员。或者调用了其他非const 成员函数。编译器将报错。这无疑会提高程序的健壮性。
    比如。下面程序中,类stack 的成员函数GetCount 仅用于计数,从逻辑上讲GetCount 应当为const 函数。编译器将指出GetCount 函数中的错误。
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;
}

    到这里,constkeyword的解说就结束了。下面是几点使用const的几点规则。
    1) const对象仅仅能訪问const成员函数,而非const对象能够訪问随意的成员函数,包含const成员函数。
    2) const对象的成员是不可改动的,然而const对象通过指针维护的对象却是能够改动的。
    3) const成员函数不能够改动对象的数据,无论对象是否具有const性质.它在编译时,以是否改动成员数据为根据,进行检查。
    4) 然而加上mutable修饰符的数据成员,对于不论什么情况下通过不论什么手段都可改动,自然此时的const成员函数是能够改动它的。

转载于:https://www.cnblogs.com/bhlsheji/p/5173445.html

相关文章:

hdu5185 dp:和为n且满足后一项是前一项或者+1的数列个数

其实是很裸的dp&#xff0c;竟然放在第四题 dp[i][j]表示当前放j和为i的方案数 dp[0][0]1; dp[i][j]dp[i-j][j-1]dp[i-j][j]; 1 #include<stdio.h>2 #include<string.h>3 #include<math.h>4 #include<algorithm>5 using namespace std;6 int dp[50005]…

2021全国高校计算机能力挑战赛(决赛)Java

计算奖品价格标准差 import java.util.*;public class Main {public static void main(String[] args) {Scanner in new Scanner(System.in);int n in.nextInt();float sum0;int total_n0;int[] numnew int[10];float[] prinew float[10];for (int i 0; i <n ; i) {num[i…

Python训练营2021:构建8个真实世界的Python项目

时长:19h 27m |视频:. MP4&#xff0c;1280720 30 fps |音频:AAC&#xff0c;44.1 kHz&#xff0c;2ch |大小:9.54 GB 语言&#xff1a;英语中英文字幕 机译 从Python Web开发的初学者到专家:学习使用SQLite、Tkinter开发真实的Django应用程序 你会学到: 了解如何使用像Djang…

SpringBoot复习:3(@Conditional)

Conditional 条件装配&#xff1a;满足Conditional指定的条件时&#xff0c;则进行组件注入 Conditional注解下面包含许多注解&#xff0c;如下图&#xff1a; 这些注解各有各的功能&#xff0c;这里挑几个来记录一下。 ConditionalOnBean注解 个人理解&#xff1a;当该注…

HDU——1106排序(istringstream的使用、STLvector练习)

排序 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 46057 Accepted Submission(s): 13221 Problem Description输入一行数字&#xff0c;如果我们把这行数字中的‘5’都看成空格&#xff0c;那么就得到一行用…

AssertValid函数学习

转自http://tsitao.blog.163.com/blog/static/29795822006914105840496/ VC的调试中&#xff0c;AssertValid和Dump函数的应用 CObject::AssertValid 成员函数提供对对象内部状态的运行时检查。虽然从 CObject 派生类时不须要重写 AssertValid&#xff0c;但能够通过重写使您的…

数值分析第一次作业-牛顿迭代法求解二元非线性方程组

1、问题 求解如下方程组: 2、算法 3、代码实现 # *coding:utf-8 * import math delta 5e-6 ;eps 1e-6 x0 1;y0 1 er 1;k 0 def z(x,y):return math.sin(x*y)*math.exp(-0.1*(x**2y**2x*y2*x)) def f(x,y):return y*math.cos(x*y)-0.1*(2*xy2)*math.sin(x*y) def g(x,y…

Maya制作风格化的女性跑步动画学习教程

时长:2h 11m |视频:. MP4 1280720&#xff0c;30 fps(r) |音频:AAC&#xff0c;48000 Hz&#xff0c;2ch |大小解压后:1.56 GB 含参考素材 流派:电子学习|语言&#xff1a;英语中英文字幕&#xff08;根据原英文字幕机译更准确&#xff09; 通过在Autodesk Maya中提供专业外观…

安卓手机抓包实战

最近因为要做一个项目&#xff0c;所以需要对手机给家电发送的请求进行抓取&#xff0c;于是上网找了许多教程&#xff0c;但都不怎么理想&#xff0c;最终经过两个晚上的艰辛奋斗&#xff0c;终于让我找到了方法抓取到了手机发送的请求&#xff0c;写一篇博客记录一下这个过程…

导入drupal中文语言包

http://lugir.com/book/export/html/399转载于:https://www.cnblogs.com/qinqiu/p/5174062.html

JavaScript引擎大战:Google提出StrongMode和SoundScript议案,增强V8性能

JavaScript 引擎性能大战硝烟迷漫&#xff0c;Chrome V8 引擎团队宣布了一个新的计划&#xff0c;在这个计划里他们介绍了两个新的虚拟机概念&#xff1a;强化模式&#xff08;StrongMode&#xff09;和强化脚本&#xff08;StrongScript&#xff09;。\\强化模式是 ES5 严格模…

数值分析第三次作业-常微分方程的数值解法

一、欧拉方法 二、修正的欧拉方法 2.1.梯形公式 将问题&#xff08;*&#xff09;的解表成积分形式&#xff0c;用数值积分方法离散化。例如&#xff0c;对微分方程

SYNCHRO 4D可视化调度学习教程 SYNCHRO 4D: Visual Scheduling

MP4 |视频:h264&#xff0c;1280720 |音频:AAC&#xff0c;44.1 KHz&#xff0c;2 Ch 技能水平:初级|流派:电子学习|语言&#xff1a;英语中英文字幕&#xff08;根据原英文字幕机译更准确&#xff09; |时长:3h 14m |大小:1.36 GB 含课程练习文件 课程获取&#xff1a;SYNCHR…

SpringBoot复习:4(@ImportResource)

ImportResource注解 作用&#xff1a;这个注解可以用来导入Spring的配置文件&#xff08;bean.xml文件&#xff09;。 适用场景&#xff1a; 可以试想一下这样一个场景&#xff0c;老板要你将原来的Spring项目改成SpringBoot项目&#xff0c;原项目底下有一大堆的bean.xml文件…

YTU 2723: 默认参数--求圆的面积

2723: 默认参数--求圆的面积 时间限制: 1 Sec 内存限制: 128 MB提交: 206 解决: 150题目描述 根据半径r求圆的面积, 如果不指定小数位数,输出结果默认保留两位小数。 部分代码已给定如下&#xff0c;只需要提交缺失的代码。 #include <iostream> #include <iomanip&…

jmeter内存溢出处理方式记录

方法一&#xff1a; 使用jmeter进行压力测试时 遇到一段时间后报内存溢出outfmenmory错误&#xff0c;导致jmeter卡死了&#xff0c;先尝试在jmeter.bat中增加了JVM_ARGS"- Xmx2048m -Xms2048m -Xmn256m -XX:PermSize128m -Xss256k"&#xff0c;但结果运行时间增加了…

支持向量机学习笔记1

1、支持向量机是一种二类分类模型。它的模型基本定义是特征空间上间隔最大的线性分类器。 2、核函数的引入&#xff0c;使得支持向量机可以进行非线性分类。 3、支持向量机也可以完成多类别分类&#xff08;将在后面介绍&#xff09; 4、支持向量机的学习策略为间隔最大化&a…

C4D入门学习教程

MP4 |视频:AVC&#xff0c;1280720 30 fps |音频:AAC&#xff0c;48 KHz&#xff0c;2 Ch |时长:2h 12m 语言&#xff1a;英语中英文字幕&#xff08;根据原英文字幕机译更准确&#xff09;|大小解压后:560M C4D是一个有抱负的运动图形艺术家和设计师的重要工具。借助C4D&#…

SpringBoot复习:5(配置绑定)

配置绑定 在SpringBoot中我们如何读取到properties文件中的内容&#xff0c;并且把它封装到JavaBean中&#xff0c;以供随时使用呢&#xff1f; 我们可以使用以下两种方式来实现。 方法一&#xff1a;ConfigurationPropertiesComponent 第一种方法&#xff0c;我们可以使用C…

是男人就下100层【第五层】——2048游戏从源代码到公布市场

上一篇《是男人就下100层【第五层】——换肤版2048游戏》中阳光小强对2048游戏用自己的方式进行了实现&#xff0c;并分享了核心源码&#xff0c;这一篇阳光小强打算将该项目的全部源码公开并结合这个实例在这篇文章中介绍一下怎样加入广告和实现分享功能。终于执行效果例如以下…

zabbix菜单出现问号乱码问题

zabbix菜单出现问号乱码问题 安装后zabbix&#xff0c;设置成中文后&#xff0c;发现菜单出现了好多的乱码&#xff0c;google之后才知道这与zabbix数据库字符集设置有关。查看当前的默认字符集&#xff1a;mysql> show create database zabbix;---------------------------…

什么是Closed-form solution?

最近看论文&#xff0c;讨论微分方程解时遇到closed-form solution概念&#xff0c;上网检索&#xff0c;找到一个较浅显易懂的解释如下。 与工学院所学的微分方程不同的是&#xff0c;工学院的学生一般都是学如何把特定的微分方程的解用基本函数&#xff08;例如多项式、三角函…

c4d中的3D插图制作视频教程 Skillshare – 3D Illustration in Cinema 4D

技能分享——C4D的3D插图 教程大小解压后&#xff1a;1.33G 1920X1080 mp4 语言&#xff1a;英语中英文字幕&#xff08;根据原英文字幕机译更准确&#xff09; C4D是众所周知的平易近人的软件&#xff0c;也是进入3D艺术梦幻世界的理想门户。 加入马特的这个课程&#xff0c…

SpringSecurity学习:1(第一个SpringSecurity项目)

此博客是记录自己学习过程的记录 第一个SpringSecurity项目 导入依赖 详细的步骤我就不多说了&#xff0c;使用IDEA创建过SpringBoot项目的人一般都能看懂。 这一步我们可以在使用IDEA创建SpringBoot项目的时候完成&#xff0c;如下图&#xff1a; 在创建SpringBoot项目时&a…

使用Struts2标签遍历集合

遍历Map<String,Object>遍历Map<Stirng,List<Student>>遍历List<Map<String,Student>>Student.java package action;public class Student {private Long sid;private String name;public Student() {// TODO Auto-generated constructor stub}p…

TortoiseGit的使用详解

然后A修改了,A想上传代码,发现冲突了,原因是A依靠的是1版本的代码进行了修改,而此时远程仓库的代码是2版本,这样当然会产生冲突。当从远程仓库拉取代码时,代码会直接拉取到工作区,然后我们要添加、提交,然后才可以把拉取的代码放入本地仓库,本地仓库的代码可以通过推送,推送到远程仓库,这是一个大循环。解决冲突的办法就是,先把远程仓库的2版本的代码进行拉取,然后TortoiseGit会列出冲突的文件代码,然后自己手动解决、选择自己需要的代码,右键选择解决冲突,最后再重新上传就可以了。点击拉取,可以下载文件。

Java的System.out.println()深入解析理解

语句来输出信息,从开始学习Java就知道用它来输出Hello World,没有深究其实现原理,现在查阅文档、源代码后记录一下。方法进行字符流输出,只是整个过程封装了许多方法来支持各种类型的变量、以及自动初始化等,使得用户能够方便快捷在控制台打印数据。变量进行了初始化,让它指向控制台,于是就可以直接使用了。的,因此即使程序中没有手动导入,也可访问到。由C/C++实现,这里只是一个接口,在。修饰的,根据Java语法,它只能调用。方法重载,因此可输出多种类型的数据。接着看,在构造方法中,先是初始化了。

第一次作业,针对软件工程这门课程提出五个疑问。

1、如果对于不爱好计算机的同学来说学习软件工程的意义大吗&#xff0c;有多大&#xff1f; 2、软件工程的知识面那么广&#xff0c;如果才能系统有效的将它学好&#xff1f; 3、软建工程这门课是否有点纸上谈兵了&#xff1f; 4、软件工程是衣门很枯燥的学科&#xff0c;我们怎…

matlab2013 a/b 找不到vs2013 c++ 编译器 解决方案

64-bit Matlab 解压附件后&#xff0c;放到 C:\Program Files\MATLAB\R2013a\bin\win64\mexopts32-bit Matlab 解压附件后&#xff0c;放到 C:\Program Files\MATLAB\R2013a\bin\win32\mexopts点我下载附件 原文出处&#xff1a;http://kaba.hilvi.org/homepage/blog/vs_201…

C4D运动图形基本训练学习教程

MP4 |视频:h264&#xff0c;1280720 |音频:AAC&#xff0c;44.1 KHz&#xff0c;2 Ch 技能水平:初级|语言&#xff1a;英语中英文字幕&#xff08;根据原英文字幕机译更准确&#xff09; |持续时间:3h 1m |大小解压后:1.7 GB 含课程练习文件 C4D继续作为3D艺术家的行业标准解决…