EC++学习笔记(一) 习惯c++
条款01:c++多范式编程语言
条款02:尽量以 const, enum, inline 替换#define
1. 提供类型安全检查
2. 去除函数调用开销
3. 避免宏的二义性
const double pi = 3.1415926;
const std::string authorName("wwwjieo0");
宏函数:所有实参必须加上小括号
#define MAX(x, y) ((x) >= (y) ? (x) : (y))
MAX(++a, b); //a被累加两次
c++ inline函数实现:
template<class T>
inline T max(const T& x, const T& y) {
return (x >= y ? x : y);
}
c语言中的宏仍然是必需品:
#include是必需品,#ifdef和#ifndef扮演 条件编译的角色
条款03:尽可能使用const
const 使编译器实施强制保护
char myname[] = "wwwjieo0";
char* p = myname; //non-const pointer, non-const data
const char* p = myname; //non-const pointer, const data
char* const p = myname; //const pointer, non-const data
const char* const p = myname; //const pointer, const data
STL迭代器的const:
const std::vector<int>::iterator it = vec.begin(); //it为const,永远指向begin
std::vector<int>::const_iterator it = vec.begin(); //it可以改变,但*it(即容器元素)不可改变
const 成员函数:
const 成员函数不可以更改对象任何non-static 成员变量
可以利用 const 成员函数实现其non-const 版本
const Widget& func(int x, int y) const; //已经实现
Widget& func(int x, int y) {
return const_cast<Widget&>(static_cast<const Widget&>(*this).func(x, y));
}
类中的每个non-static 成员函数都有一个隐藏的this参数(第一个参数),这个this指针指向类的实例对象,并且this指针为const pointer
所以 Widget& func(int x, int y) 实际上是 Widget& func(Widget* const this, int x, int y);
而 const 成员版本 Widget& func(int x, int y) const 实际上是 Widget& func(const Widget * const this, int x, int y);
(const int& x)和 (const int x)是重载函数,并不是重复定义
static_cast 将(*this) 加上 const 特性,因为要调用 const 成员函数
const_cast 将 const 成员函数返回值 const Widget& 去除 const 特性,因为要与函数返回值类型相同
注意:不能用non-const 成员函数去实现相应的 const 版本,因为 non-const 函数可能会改变一些值,这不符合 const 函数的要求
条款04:确定对象被使用前已被初始化
永远在使用对象之前先将它初始化:
内置类型:手工初始化,避免未定义行为带来的随机值
自定义类型:确保每一个构造函数都将对象的每一个成员初始化
class Person{
public:
Person(const string& name, const string& address);
private:
string theName;
string theAddress;
int theId;
}; Person::Person(const string& name, const string& address) {
theName = name;
theAddress = address;
theId = ;
}
c++规定,对象的成员变量的初始化动作发生在进入构造函数的函数体之前
所以上面程序中,构造函数内部并不是初始化,而是赋值操作
真正的初始化动作发生在 default 构造函数(编译器自动生成)自动调用之时
构造函数应该使用 成员初始化列表 替换赋值操作
Person::Person(const string& name, const string& address)
:theName(name),
theAddress(address),
theId()
{ }
这种方法效率更高,没有首先调用 default 构造函数,而是在进入构造函数的函数体之前利用 copy构造函数直接初始化
总结:总是使用成员初始值列表,并且在初值中列出所有成员变量
c++初始化次序:base class 更早于 derived class,class 的成员变量总是以其声明次序被初始化
EC++学习笔记(一) 习惯c++的更多相关文章
- EC++学习笔记(二) 构造/析构/赋值
条款05:了解c++默默编写并调用了哪些函数 编译器可以暗自为 class 创建default构造函数,copy构造函数,copy assignment操作和析构函数所有这些函数都是 public 并 ...
- EC++学习笔记(三) 资源管理
条款13:以对象管理资源 资源包括:动态分配内存.文件描述符.网络socket.互斥锁.数据库连接 把资源放进对象内,可以依赖c++的"析构函数自动调用机制"确保资源被释放智能指针 ...
- EC++学习笔记(四) 设计与声明
条款18:让接口容易被正确使用,不易被误用 必须考虑客户可能做出什么样的错误(防御式编程)std:shared_ptr会自动使用它的"每个指针专属的删除器",消除了"cr ...
- EC++学习笔记(五) 实现
条款26:尽可能延后变量定义式的出现时间 尽可能延后变量的定义,知道非得使用该变量的前一刻为止方法A: Widget W; ; i < n; ++i) { W = ... } 方法B: ; i ...
- EC++学习笔记(六) 继承和面向对象设计
条款32:确定你的 public 继承塑模出 is-a 关系 public inheritance 意味着 is-a 关系class Derived 以 public 形式继承 class Base, ...
- SQLServer学习笔记系列1
一.前言 一直自己没有学习做笔记的习惯,所以为了加强自己对知识的深入理解,决定将学习笔记写下来,希望向各位大牛们学习交流! 不当之处请斧正!在此感谢!这边就先从学习Sqlserver写起,自己本身对数 ...
- PyQt4入门学习笔记(一)
PyQt4入门学习笔记(一) 一直没有找到什么好的pyqt4的教程,偶然在google上搜到一篇不错的入门文档,翻译过来,留以后再复习. 原始链接如下: http://zetcode.com/gui/ ...
- Linux 学习笔记
Linux学习笔记 请切换web视图查看,表格比较大,方法:视图>>web板式视图 博客园不能粘贴图片吗 http://wenku.baidu.com/view/bda1c3067fd53 ...
- 《Java学习笔记(第8版)》学习指导
<Java学习笔记(第8版)>学习指导 目录 图书简况 学习指导 第一章 Java平台概论 第二章 从JDK到IDE 第三章 基础语法 第四章 认识对象 第五章 对象封装 第六章 继承与多 ...
随机推荐
- JavaScript的语音识别
有没有想过给您的网站增添语音识别的功能?比如您的用户不用点鼠标,仅仅通过电脑或者手机的麦克风发布命令,比如"下拉到页面底部",或者"跳转到下一页",您的网站就会 ...
- ImportError: No module named flask.ext.wtf 解决方法
install pip install flask.ext.wtf
- python基础面试题整理---从零开始 每天十题(01)
最近在弄flask的东西,好久没写博客的,感觉少了点什么,感觉被别人落下好多,可能渐渐的养成了写博客的习惯吧.也是自己想学的东西太多了(说白了就是基础太差了,只是know how,不能做到konw w ...
- EMVS: Event-based Multi-View Stereo 阅读笔记
0. 摘要 EMVS目的:从已知轨迹的event相机,估计半稠密的3D结构 传统的MVS算法目的:从已知视点的图片集,去估计场景的稠密3D结构. EMVS2个固有属性: (1) 当传感器发生相对运 ...
- Workrave怎么用 Workrave使用方法, Workrave 健康计时器,预防电脑长期操作的职业病伤害
下载绿色版: https://portableapps.com/apps/utilities/workrave_portable 选择阅读模式: 中文: 可以只选择启动休息的计时器,这样其他2个就不用 ...
- jQuery实现滚动条下拉时无限加载
var lastId=0;//记录每一次加载时的最后一条记录id,跟您的排序方式有关. var isloading = false; $(window).bind("scroll" ...
- Python自动化测试框架——数据驱动(从代码中读取)
今天小编要介绍的是数据驱动最简单和最常用的一种方法,由于只是介绍方法,代码操作后的美观程度略有缺陷,介意者可以自行改动 还是以163邮箱登录为例: 设计一个存放数据的类,这个类的参数是我们需要修改的数 ...
- 主DNS服务-反向解析
上篇说了主DNS正向解析 当中是有个小问题的,什么问题呢? 试问当我们输入wwww或ww或更多w的时候它还能解析出来吗? 或者不输入w的时候还能解析吗? 上篇没有定义是解析不了的,怎么定义呢?很简单, ...
- requests库的学习——跟随官方文档
发送GET请求: import requests r=requests.get("http://www.kekenet.com/") 如果需要传递参数可以有以下几种方法: impo ...
- SVN如何避免冲突
在团队开发时,必然会用到代码版本控制工具,比如SVN. 但是多人共同维护同一份代码,当对同一文件进行增删时,就可能造成冲突,如何尽可能避免冲突相当重要. 首先,每次,新建任何文档,都会修改项目文件,所 ...