C++——const
参考:https://www.cnblogs.com/Forever-Kenlen-Ja/p/3776991.html
1.使用前必须初始化(编译时初始化,运行时初始化)
2.extern const
extern const int buffSize=255;//file1
extern const int buffSize;//file2,包含file1,extern可以使得其被其他文件使用,避免多次定义
const int a = ; //修饰变量,a不能该内容(更改为其他的值)
int* const p = &a;//修饰指针,a可变,但p只能指向a,不能指向其他变量名
const int *p = ;//修饰指针指向的内容,不能改内容
const int * const p = &a;//既修饰指针,又修饰指针指向的内容:p不能指向别的变量,a的值也不能改 void fun(const int a);//修饰传参,可要可不要const
void fun(int *const a)//修饰传参指针,
void fun(const int &a);//const+类型+引用传递(一般用于自定义类型),const 引用可以在保证参数不被修改的前提下,防止数据的值传递拷贝 const int fun(){ return ;}//修饰函数返回值
const myType fun(){ return ;}//修饰返回值,自定义类型,
const int &fun(){ return i;}//修饰返回值的引用,//返回值不能是局部变量
int *const fun(){ return &i;}//修饰返回值的指针,//返回值不能是局部变量 int get() const { return ;}//修饰类成员函数,不能修改对象的数据成员而且不能调用非const函数
void func(const A& a, int b, const int* c, int* d)const;//显然,上述成员函数中,a为const引用传递,不可以改变原值;b为值传递;c为const指针传递,不可改变原值;d为输出参数,可以改变原值。而该函数为const成员函数,不可以修改成员变量值。
1.修饰变量,不对,修饰的是一个不可变的量
const int a = ; int b = a; //it's right a = ; // it's wrong,
取变量的地址并转换赋值给 指向int的指针,也改不了
const int a = ;
int *p = (int*)&a;
*p = ;
2.修饰指针
A:const 修饰指针指向的内容,则内容为不可变量。
const int *p = ;
B:const 修饰指针,则指针为不可变量。(p其指向的内存地址不能够被改变,但其内容可以改变。)
int a = ;
int* const p = &a;
*p = ; //it’s right
int b = ;
p = &b; //it’s wrong
C:const 修饰指针和指针指向的内容,则指针和指针指向的内容都为不可变量。
int a = ;
const int * const p = &a;

3.const参数传递
A:值传递的const修饰传递(一般这种情况不需要const修饰,因为函数会自动产生临时变量复制实参值,实参值本身就是不可改变的)
#include<iostream>
using namespace std; void Cpf(const int a)
{
cout<<a;
// ++a; it's wrong, a can't be changed.
// a=10; it's wrong, a can't be changed. }
void Cpf1(int a)
{
cout<<a;
// ++a; it's wrong, a can't be changed.
// a=10; it's wrong, a can't be changed. }
int main(void)
{
Cpf();
Cpf1();
system("pause"); return ;
}
B:当const参数为指针时,可以防止指针被意外篡改。(但是指针指向的值可以改)(作用是什么呢?)
#include<iostream>
using namespace std; void Cpf(int *const a)
{
cout<<*a<<" ";
*a = ;
} int main(void)
{
int a = ;
Cpf(&a);
cout<<a; // a is 9 system("pause");
return ;
}
C:const+自定义类型+引用传递
对于一般的int ,double等内置类型,我们不采用引用的传递方式;
自定义类型的参数传递,需要临时对象复制参数,对于临时对象的构造,需要调用构造函数,比较浪费时间,因此我们采取const外加引用传递的方法
#include<iostream>
using namespace std; class Test
{
public:
Test(){}
Test(int _m):_cm(_m){} int get_cm()
{
return _cm;
}
private:
int _cm;
}; void Cmf(const Test& _tt)//const+自定义类型+引用传递
{
cout<<_tt.get_cm();
} int main(void)
{
Test t();
Cmf(t); system("pause");
return ;
}
4.const修饰函数的返回值
归根究底就是使得函数调用表达式不能作为左值。
A:const修饰内置类型的返回值,修饰与不修饰返回值作用一样。
#include<iostream>
using namespace std; const int Cmf()
{
return ;
} int Cpf()
{
return ;
} int main(void)
{ int _m = Cmf();
int _n = Cpf(); cout<<_m<<" "<<_n; system("pause");
return ;
}
#include <iostream>
using namespace std; class A {
private:
int i;
public:
A(){i=;}
int & get(){
return i;
}
}; void main(){
A a;
cout<<a.get()<<endl; //数据成员值为0
a.get()=; //尝试修改a对象的数据成员为1,而且是用函数调用表达式作为左值。
cout<<a.get()<<endl; //数据成员真的被改为1了,返回指针的情况也可以修改成员i的值,所以为了安全起见最好在返回值加上const,使得函数调用表达式不能作为左值
}
B:const 修饰自定义类型的作为返回值,此时返回的值不能作为左值使用,既不能被赋值,也不能被修改。
C: const 修饰返回的指针或者引用,是否返回一个指向const的指针,取决于我们想让用户干什么。
- 不能返回对局部对象的引用
// Disaster: Function returns a reference to a local object
const string &manip(const string& s)
{
string ret = s;
// transform ret in some way
return ret; // Wrong: Returning reference to a local object!//返回对局部对象的引用就会指向不确定的内存。
}
- 不能返回指向局部对象的指针
- 当函数返回引用类型时,没有复制返回值。相反,返回的是对象本身。
例如,考虑下面的函数,此函数返回两个 string 类型形参中较短的那个字符串的引用:
const string &shorterString(const string &s1, const string &s2)
{
return s1.size() < s2.size() ? s1 : s2;
}
5.const修饰类成员函数
防止成员函数修改被调用对象的值。
如果我们不想修改一个调用对象的值,所有的成员函数都应当声明为const成员函数。
注意:const关键字不能与static关键字同时使用,因为static关键字修饰静态成员函数,静态成员函数不含有this指针,即不能实例化,const成员函数必须具体到某一实例。
#include <iostream>
using namespace std; class A{
private:
int i;
public:
void set(int n){ //set函数需要设置i的值,所以不能声明为const
i = n;
} int get() const{ //get函数返回i的值,不需要对i进行修改,则可以用const修饰。防止在函数体内对i进行修改。
return i;
}
};
在该函数体内,不能修改对象的数据成员而且不能调用非const函数。为什么不能调用非const函数?因为非const函数可能修改数据成员,const成员函数是不能修改数据成员的,所以在const成员函数内只能调用const函数。
5.1 以下是const成员函数注意的几点:
1)const对象只能访问const成员函数,而非const对象可以访问任意的成员函数,包括const成员函数.即对于class A,有
const A a;
那么a只能访问A的const成员函数。而对于:
A b;
b可以访问任何成员函数。
2)const对象的成员变量不可以修改。
3)mutable修饰的成员变量,在任何情况下都可以修改。也就是说,const成员函数也可以修改mutable修饰的成员变量。c++很shit的地方就是mutable和friendly这样的特性,很乱。
4)const成员函数可以访问const成员变量和非const成员变量,但不能修改任何变量。检查发生在编译时。
5)非const成员函数可以访问非const对象的非const数据成员、const数据成员,但不可以访问const对象的任意数据成员。
6)const成员函数只是用于非静态成员函数,不能用于静态成员函数。
7)const成员函数的const修饰不仅在函数声明中要加(包括内联函数),在类外定义出也要加。
8)作为一种良好的编程风格,在声明一个成员函数时,若该成员函数并不对数据成员进行修改操作,应尽可能将该成员函数声明为const 成员函数。
6.const 引用


C++——const的更多相关文章
- openssl 1.1.1 reference
openssl 1.1.1 include/openssl aes.h: # define HEADER_AES_H aes.h: # define AES_ENCRYPT 1 aes.h: # de ...
- const,static,extern 简介
const,static,extern 简介 一.const与宏的区别: const简介:之前常用的字符串常量,一般是抽成宏,但是苹果不推荐我们抽成宏,推荐我们使用const常量. 执行时刻:宏是预编 ...
- C++中的const
一,C++中const的基本知识 1.C++中const的基本概念 1.const是定义常量的关键字,表示只读,不可以修改. 2.const在定义常量的时候必须要初始化,否则报错,因为常量无法修改,只 ...
- const extern static 终极指南
const extern static 终极指南 不管是从事哪种语言的开发工作,const extern static 这三个关键字的用法和原理都是我们必须明白的.本文将对此做出非常详细的讲解. co ...
- const let,console.log('a',a)跟console.log('a'+a)的区别
const 创建一个只读的常量 let块级作用域 const let重复赋值都会报错 console.log('a',a) a console.log('a'+a) a2 逗号的值会有空格:用加号的值 ...
- es6之let和const
在javascript中,我们都知道使用var来声明变量.javascript是函数级作用域,函数内可以访问函数外的变量,函数外不能访问函数内的变量. 函数级作用域会导致一些问题就是某些代码块内的变量 ...
- construction const parameter问题 构造函数const引用参数问题
工程在window下编译没有任何问题, 但是在linux(CentOS6)下编译就老是报错 C++ 编译器已升级到最新版 6.1.0 错误如下: In file included /bits/stl_ ...
- Error:const char* 类型的实参和LPCWSTR类型的形参不兼容的解决方法。
在C++的Windows 应用程序中经常碰到这种情况. 解决方法: 加入如下转换函数: LPCWSTR stringToLPCWSTR(std::string orig) { size_t origs ...
- C#基础知识七之const和readonly关键字
前言 不知道大家对const和readonly关键字两者的区别了解多少,如果你也不是很清楚的话,那就一起来探讨吧!探讨之前我们先来了解静态常量和动态常量. 静态常量 所谓静态常量就是在编译期间会对变量 ...
- const 与 readonly知多少
原文地址: http://www.cnblogs.com/royenhome/archive/2010/05/22/1741592.html 尽管你写了很多年的C#的代码,但是可能当别人问到你cons ...
随机推荐
- javascript给输入框赋值的一个误区
一. 错误的示范 如下代码所示,如果需要用javascript获取id为username1, password1的输入框的值,将其写入id为username2, password2的输入框,那么红线区 ...
- 去掉标题栏的方法(使用requestWindowFeature(Window.FEATURE_NO_TITLE);为什么失效?不仅失效,可能会挂)
使用requestWindowFeature(Window.FEATURE_NO_TITLE)隐藏标题栏失效的原因,不仅失效,可能会挂.可能是activity继承的是AppCompatActivity ...
- 通过Intent 打开系统级应用
众所周知,各个手机厂商由于对Android 原生系统定制的原因,会造成系统级应用packname 和activityname 不同的现象,就拿时钟软件来说,魅族2的activityname 是[com ...
- Python正则表达式之 - ?: / ?= / ?!
Python正则表达式之 - ?: / ?= / ?! 用圆括号将所有选择项括起来,相邻的选择项之间用|分隔.但用圆括号会有一个副作用,使相关的匹配会被缓存,此时可用?:放在第一个选项前来消除这种副作 ...
- Microsoft Visual Studio 2012 Update 4 RC 3 离线安装程序
Microsoft Visual Studio 2012 Update 4 RC 3 离线安装程序 ☆ 微软官网地址:☆ http://www.microsoft.com/en-us/download ...
- Mycat 在vscode中的开发配置
mycat是国产目前最被追捧的一款分布式数据库集群软件,有一些公司对数据库和应用都有自己的集群方案,但是更多的是一些面对庞大的数据量,而束手无策. 对于这种问题,我想百分之80遇到的是数据库的瓶颈,所 ...
- swing之JDialog
package canying; import java.awt.Color; import java.awt.Graphics; import java.awt.Image; import java ...
- iptables的启动和关闭【转载】
原文网址:http://os.51cto.com/art/201103/249049.htm iptables的启动和关闭: 1.启动和关闭iptables 下面将正式使用iptables来创建防火墙 ...
- Web中的安全性问题
根据2010年OWASP发布的Web应用程序安全风险主要是SQL注入攻击.跨网站脚本.伪造客户端请求.Cookie盗取,传输层保护不足. 1 SQL注入攻击 随着B/S框架结构在系统开发中的广泛应用 ...
- Linux应用函数 -- 字符串
1.strchr 原型 char *strchr(const char* _Str,char _Val) 头文件 string.h 功能 查找字符串_Str中首次出现字符_Val的位置 返回值 成功 ...