参考: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的更多相关文章

  1. 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 ...

  2. const,static,extern 简介

    const,static,extern 简介 一.const与宏的区别: const简介:之前常用的字符串常量,一般是抽成宏,但是苹果不推荐我们抽成宏,推荐我们使用const常量. 执行时刻:宏是预编 ...

  3. C++中的const

    一,C++中const的基本知识 1.C++中const的基本概念 1.const是定义常量的关键字,表示只读,不可以修改. 2.const在定义常量的时候必须要初始化,否则报错,因为常量无法修改,只 ...

  4. const extern static 终极指南

    const extern static 终极指南 不管是从事哪种语言的开发工作,const extern static 这三个关键字的用法和原理都是我们必须明白的.本文将对此做出非常详细的讲解. co ...

  5. const let,console.log('a',a)跟console.log('a'+a)的区别

    const 创建一个只读的常量 let块级作用域 const let重复赋值都会报错 console.log('a',a) a console.log('a'+a) a2 逗号的值会有空格:用加号的值 ...

  6. es6之let和const

    在javascript中,我们都知道使用var来声明变量.javascript是函数级作用域,函数内可以访问函数外的变量,函数外不能访问函数内的变量. 函数级作用域会导致一些问题就是某些代码块内的变量 ...

  7. construction const parameter问题 构造函数const引用参数问题

    工程在window下编译没有任何问题, 但是在linux(CentOS6)下编译就老是报错 C++ 编译器已升级到最新版 6.1.0 错误如下: In file included /bits/stl_ ...

  8. Error:const char* 类型的实参和LPCWSTR类型的形参不兼容的解决方法。

    在C++的Windows 应用程序中经常碰到这种情况. 解决方法: 加入如下转换函数: LPCWSTR stringToLPCWSTR(std::string orig) { size_t origs ...

  9. C#基础知识七之const和readonly关键字

    前言 不知道大家对const和readonly关键字两者的区别了解多少,如果你也不是很清楚的话,那就一起来探讨吧!探讨之前我们先来了解静态常量和动态常量. 静态常量 所谓静态常量就是在编译期间会对变量 ...

  10. const 与 readonly知多少

    原文地址: http://www.cnblogs.com/royenhome/archive/2010/05/22/1741592.html 尽管你写了很多年的C#的代码,但是可能当别人问到你cons ...

随机推荐

  1. SQL1221N The Application Support Layer heap cannot be allocated. SQLSTATE=57011

    不能分配“应用程序支持层“堆 内存不足(系统中可用的调页空间量或交换空间量或系统中可用的物理内存量),可能会导致问题,并提示如下错误信息: SQL1221N  The Application Supp ...

  2. java学习笔记 --- IO(1)

    1.File类:文件和目录(文件夹)路径名的抽象表示形式,把文件或者目录(文件夹)都封装成File对象 1.构造方法 File(String pathname):根据一个路径得到File对象 File ...

  3. python编程实例-使用正则收集IP信息

    #!/usr/bin/env python from subprocess import PIPE,Popen import re def getIfconfig(): p = Popen(['ifc ...

  4. NHibernate常见错误汇总

    NHibernateSample.Data.Test.QueryHQLFixture.WhereTest: NHibernate.Hql.Ast.ANTLR.QuerySyntaxException ...

  5. New Concept English three (56)

    The river which forms the eastern boundary of our farm has always played an important part in our li ...

  6. CANopenSocket CANopenCGI.c hacking

    /**************************************************************************************** * CANopenS ...

  7. XML数据库的尝试

    首先祝大家新年快乐.身体健康,平安就是福气. 对于一般的个人迷你项目,数据量不大的时候,完全没有必要使用数据库,管理数据使用XML就可以了. 自己尝试写了一个XML数据库,插入1w条小记录,大概3M大 ...

  8. 预备架构的工具ADMEMS矩阵

    矩阵,是很多著名方法的核心.例如,制定公司层战略的方法之一是"波士顿矩阵","波士顿矩阵"又称"市场增长率-相对市场份额矩阵". " ...

  9. 第七篇 PHP编码规范

    当码农多年,始终进步不大,前面说了第一个原因是没有明确的目标:第二个原因是没有养成良好的习惯(即优秀的职业规范). 1)pear 规范 http://pear.php.net/manual/en/st ...

  10. CEF源码编译

    CEF的构造说明:https://bitbucket.org/chromiumembedded/cef/wiki/BranchesAndBuilding chromium的源码地址:https://c ...