定义常量

  • define 是一个Compile-Time的概念,它的生命周期止于编译器期,它存在与程序的代码段,在实际程序中它只是一个常数、一个命令中的参数、并没有实际的存在
  • const常量存在于程序的数据段,并在堆栈分配了空间。const常量是一个Run-Time的概念,它在程序中确确实实地存在并可以被调用、传递。const常量有数据类型,而宏常量没有数据类型。编译器可以对const常量进行类型安全检查
const int val = 5;
const char* const p = "hello";
const std::string str{ "world" };

修饰指针变量

当const出现在星号左边,表示被指物是常量;如果出现在星号右边,表示指针自身是常量;如果出现在星号两边,表示被指物和指针两者都是常量

const char * p;(此处可以不初始化) p指向的内容是常量
char *const p; p本身是常量
const char * const p; p和p指向的内容都是常量

修饰引用

int num1 = 8;
const int & num2 = num1; //常引用,不能通过引用去修改被引用的指(引用必须初始化)
int & const num3 = num1; //error
const int & const num4 = num1; //error

修饰函数

修饰函数参数

如果不需要改动参数或local对象,尽量加上const:

  • 防止创建副本,减少内存开销
  • 防止对引用参数进行修改
void func(const std::string & str);

修饰函数返回值

令函数返回一个常量指,往往可以降低因客户错误而造成的意外,而不至于放弃安全性和高效性

const int func(void);

在类中的使用const

修饰成员变量

  • 常成员变量,通过构造函数对其初始化,且只能通过初始化列表的方式初始化
  • 一经初始化就不可改变
class A{
public:
/* A(int a, std::string str){
m_a = a;
m_name = str;
} */ A(int a, std::string str):m_a(a),m_name(str)
{
} public:
const int m_a;
const std::string & m_name;
};

修饰成员函数

const修饰成员函数,本质修饰的是this指针;

  • 使class的接口比较容易被理解;清楚的知道哪个函数可以改动对象内容而哪个函数不行
  • 使操作const对象成为可能
  • 两个成员函数如果只是常量性不同,可以被重载
class TextBlock{
public:
const char& operator[](std::size_t position)const
{
return text[position];
} char& operator[](std::size_t position)
{
return
const_cast<char&>( //将op[]的返回值移除const
static_cast<const TextBlock&>(*this)[position] //为*this加上const,调用[]
);
} private:
std::string text;
};

修饰对象

常对象只能调用常成员函数;普通对象既可以调用常成员函数也可以调用普通成员函数

class A{
public:
/* A(int a, std::string str){
m_a = a;
m_name = str;
} */ A(int a, std::string str):m_a(a),m_name(str)
{
} void get()const
{
std::cout << "call const A& A::get()const" << std::endl;
std::cout << this->m_a << ' ' << this->m_name << ' ' << std::endl;
} void get()
{
std::cout << "call A& A::get()" << std::endl;
std::cout << this->m_a << ' ' << this->m_name << ' ' << std::endl;
// return static_cast<const A&>(*this).get();
} public:
const int m_a;
const std::string & m_name;
}; void test()
{
A a(8,"hello");
a.get(); const A ca(9, "world");
ca.get();
}

 

  • 将某些东西声明为const可帮助编译器侦测出错误用法。const可被施加于任何作用域内的对象、函数参数、函数返回类、成员函数本体
  • 编译器强制实施bitwise constness,但你编写程序是应该使用“概念上的常量性”(conceptual constness)
  • 当const 和 non-const成员函数有着实质等价的实现时,令non-const版本调用const可避免代码重复

条款03:尽肯使用const的更多相关文章

  1. 条款03:尽可能使用const

    目录 1. 总结 2. const对象 3. const函数返回值和函数参数 4. const成员函数 const成员函数的重要性 bitwise constness logical constnes ...

  2. Effective C++ 条款03:尽可能使用const

    场景一 用于修饰指针 char greeting[] = "Hello"; char* p = greeting; // non-const pointer, non-const ...

  3. 【Effective C++ 读书笔记】条款03: 尽量使用 const

    关键字const多才多艺,变化多端却不高深莫测. const 修饰指针 面对指针, 你可以指出 指针自身.指针所指物.或者两者都不是 const. 如果关键字 const 出现在星号左边,表示被指物是 ...

  4. 《Effective C++ 》学习笔记——条款03

    ***************************************转载请注明出处:http://blog.csdn.net/lttree************************** ...

  5. 【Effective C++ 读书笔记】条款02: 尽量以 const, enum, inline 替换 #define

    条款02: 尽量以 const, enum, inline 替换 #define 这个条款或许可以改为“宁可以编译器替换预处理器”. 编译过程: .c文件--预处理-->.i文件--编译--&g ...

  6. Effective C++ -----条款03:尽可能使用const

    如果关键字const出现在星号左边,表示被指物是常量:如果出现在星号右边,表示指针自身是常量:如果出现在星号两边,表示被指物和指针两者都是常量. char greeting[] = " he ...

  7. 《Effective C++》读书笔记 条款03 尽可能使用const 使代码更加健壮

    如果你对const足够了解,只需记住以下结论即可: 将某些东西声明为const可帮助编译器侦测出错误用法,const可被施加于任何作用于内的对象.函数参数.函数返回类型.成员函数本体. 编译器强制实施 ...

  8. 条款03 尽可能使用const

    一.概述 使用const约束对象:可以获得编译器的帮助(指出相关出错的地方) const与成员函数:const重载.转型.避免代码重复 二.细节 1. 为什么有些函数要返回const对象(看上去没必要 ...

  9. 读书笔记_Effective_C++_条款二:尽量以const, enum, inline替换#define

    其实这个条款分成两部分介绍会比较好,第一部分是用const和enum替换不带参的宏,第二部分是用inline替换带参的宏. 第一部分:用const和enum替换不带参宏 宏定义#define发生在预编 ...

随机推荐

  1. linux分析利刃之sar命令详解

    一.sar的概述 在我使用的众多linux分析工具中,sar是一个非常全面的一个分析工具,可以比较瑞士军刀,对文件的读写,系统调用的使用情况,磁盘IO,CPU相关使用情况,内存使用情况,进程活动等都可 ...

  2. 解决mac OSX下安装git出现的"git命令需要使用开发者工具。您要现在安装该工具吗"(19款Mac)

    1.本地安装Git ,这里不做说明 2.命令行执行 sudo mv /usr/bin/git /usr/bin/git-system 3.如果提示 权限不足,操作不被允许,关闭Rootless,重启按 ...

  3. 基于Linux的kfifo移植到STM32(支持os的互斥访问)

    基于Linux的kfifo移植到STM32(支持os的互斥访问) 关于kfifo kfifo是内核里面的一个First In First Out数据结构,它采用环形循环队列的数据结构来实现:它提供一个 ...

  4. java IO、NIO、AIO详解

    概述 在我们学习Java的IO流之前,我们都要了解几个关键词 同步与异步(synchronous/asynchronous):同步是一种可靠的有序运行机制,当我们进行同步操作时,后续的任务是等待当前调 ...

  5. Spring bean的作用域以及生命周期

    一.request与session的区别 request简介 request范围较小一些,只是一个请求. request对象的生命周期是针对一个客户端(说确切点就是一个浏览器应用程序)的一次请求,当请 ...

  6. 用 Sphinx 搭建博客时,如何自定义插件?

    之前有不少同学看过我的个人博客(http://python-online.cn),也根据我写的教程完成了自己个人站点的搭建. 点此:使用 Python 30分钟 教你快速搭建一个博客 为防有的同学不清 ...

  7. Kubernetes之Flannel介绍

    Flannel是CoreOS团队针对Kubernetes设计的一个网络规划服务,简单来说,它的功能是让集群中的不同节点主机创建的Docker容器都具有全集群唯一的虚拟IP地址. 在Kubernetes ...

  8. Java自动化测试框架-03 - TestNG之Test Group篇 - 我们一起组团打怪升级(详细教程)

    简介 其实这篇文章的group宏哥在上一篇中就提到过,但是就是举例一笔带过的,因此今天专门有一篇文章来讲解Group的相关知识.希望大家茅塞顿开 ,有着更进一步认识和了解测试组. 一.Test Gro ...

  9. Ubuntu php + apache

    Ubuntu 环境: 问题1: apache 不能解析 *.php 文件 安装apache的扩展模块 :  apt-get install libapache2-mod-php 问题2 : 客户端访问 ...

  10. Unix 线程改变创建进程中变量的值(2)

    执行环境:Linux ubuntu 4.4.0-31-generic #50-Ubuntu SMP Wed Jul 13 00:07:12 UTC 2016 x86_64 x86_64 x86_64 ...