effective C++ 阅读笔记 1
来源:互联网 发布:《算法统宗》的题目 编辑:程序博客网 时间:2024/05/18 03:58
std::size_t:位于命名空间std,无符号类型
STL是C++标准程序库的一部分
参数:lhs,rhs
01
C++:组成;
C
面向对象的C++
TEMPLATE C++
STL 容器,迭代器,算法,函数对象的实现
02
const ,enum,inline代替#define
const int pi=3.14;
类中:不能使用define
staticconst int num=5;
intsocres[num];
或者
enum{num=5}; 取地址不合法
intsocres[num];
宏使用define可能误用
#define CALL_WITH_MAX(a,b)f((a)>(b)?(a):(b))
int a=5,b=0;
CALL_WITH_MAX(++a,b);a被加1次
CALL_WITH_MAX(++a,b+10);加2次
建议:
纯常量,以const或enums替代#define
类似函数的宏,改用inline函数代替define
03
尽可能使用const
void f1(const widget* pw)
void f1(widget const * pw)等价
const 成员函数不可以更改对象内任何非static成员变量
除非加上mutable(const函数内可以修改成员变量了)
const ,非const成员函数中避免重复的方法:
非const调用const版本避免代码重复
例如:
const char &operator[](std::size_tposition)const
{
.....
...
...
return text[position];
}
char&operator[](std::size_t position)
{
.....
...
...
return
const_cast<char &>(static_cast<const text&>(*this));
}
\\
04 对象使用前被初始化
对象初始化和赋值的区别:
初始化列表----初始化
:thename(name),theaddress(address)
{}
但--构造函数体内使用赋值
{
the name=name;
theaddress=address;赋值,不是初始化
}
05 C++自动编写哪些函数
empty e1;默认构造函数
empty e2(e1);拷贝构造函数
e2=e1;赋值操作符
析构函数
06
不想使用编译器自动生成的函数,就应该明确拒绝
方法一:继承自:privateuncopyable
方法二:成员函数声明为private,并且不实现
07
多态基类声明virtual析构函数
作用:避免资源泄漏
一个对象经由基类指针,被删除是,基类需要虚析构函数
使用场合:一般类有一个虚函数,才声明虚析构函数
纯虚函数:声明,不实现
抽象类不能定义对象,仅仅引用&,指针*
必须为纯虚析构函数提供定义:因为派生后,每一个基类的析构函数都要被调用。
什么时候定义虚析构函数?
带多态性质的基类/带有虚函数:定义虚析构函数
但:若基类不是为了多态用途或不用做基类,不需要虚析
构函数;
例如:string STL容器不用做基类,
08异常不逃出析构函数
C++并没有禁止析构函数吐出异常
不吐出异常的原因?
因为:过早结束程序或未定义行为
建议;析构函数不抛出异常。若析构函数调用的函数可能发生异常,让析构函数捕捉异常,吞下异常或结束程序
09不在构造函数,析构函数中调用虚函数
因为:基类构造期间虚函数不会下降到派生类层次,即在基类构造期间,虚函数不是虚函数
基类的构造函数执行早于派生类的构造函数,
当基类构造函数执行时派生类的成员变量未初始化。
此时调用的虚函数不会下降到派生类层次。(取用未初始化的成分是危险的)
更根本的原因:派生类对象的基类构造期间,对象的类型是基类
此时虚函数,运行期类型信息,例如dynamic_cast,typeid,都把对象当成基类
同理,适用于析构函数。一旦派生类析构函数开始执行,对象内的派生类成员变量呈现未定义,
办法:构造函数,析构函数不调用虚函数;
或者派生类构造函数中把参数传递给基类构造函数
10 operator=返回一个指向*this的引用
注意两点:
(1) x=y=z=15; 必须返回引用
(2) 返回*this
例如
widget& operator =(int rhs)
{
...
return *this;
}
11 operator =处理自我赋值
class widget{};
widget w;
w=w;
实现:
方法一:
复制pb所指的东西前别删除pb;
widget&
widget:;operator=(const widget& rhs)
{
bitmap *porig=pb; 不是最高效的 复件,删除原来的,指向新的
pb=new bitmap(*rhs.pb);
delete porig;
return *this;
}
方法二:copy and swap
class widget{
void swap(widget&rhs);
};
widget&widget::operator(constwidget&rhs)
{
widget temp(rhs):
swap(temp):
return *this;
}
或者传递值 多了副本
widget&widget::operator(const widgetrhs)
{
swap(rhs):
return *this;
}
其他不异常安全的实现:
widget&
widget:;operator=(const widget& rhs)
{
delete pb; 不异常安全
pb=new bitmap(*rhs.pb);
return *this;
}
自我赋值检测
widget&
widget:;operator=(const widget& rhs)
{
if(this==&rhs) return *this;
delete pb; 不异常安全
pb=new bitmap(*rhs.pb);//可能产生异常
return *this;
}
12 复制对象时要复制每一个成分
实现构造函数时—若初始化列表中实现----- 调用基类的拷贝构造函数
若构造函数体体实现----------调用基类的赋值函数
拷贝构造函数+赋值操作符可以消除重复---二者调用公共的函数
不要使用拷贝构造函数调用赋值操作符
- 《Effective C++》阅读笔记
- 《Effective C++》阅读笔记
- 《Effective C++》阅读笔记01
- 《Effective C++》阅读笔记02
- 《Effective C++》阅读笔记03
- 侯捷 more effective c++(WQ中文版) 阅读笔记1
- effective C++ 阅读笔记 1
- Effective c++ 阅读笔记1
- 《Effective C++》阅读笔记一:概述
- <<Effective C++>>笔记1
- Effective C++ 阅读笔记(1)
- 《Effective Java》(1~2)阅读笔记
- Effective C++阅读笔记
- effective stl 阅读笔记
- Effective Java 阅读笔记
- Effective C++ 阅读笔记
- Effective Java阅读笔记
- 《Effective c++》阅读笔记二:让自己习惯于C++
- $.ajax
- 【快速参考】SQL
- auto_ptr
- 在服务器端判断request来自Ajax请求(异步)还是传统请求(同步)
- VC6.0中clw、ncb、aps文件的作用
- effective C++ 阅读笔记 1
- C内存对齐
- Asp.net MVC area文件夹下设置默认显示页面
- NYOJ 525 一道水题
- 自定义“打开/另存为”对话框左侧快捷方式列表
- XP远程桌面mstsc和带参数的mstsc /console
- Cocos2d的特性
- Hadoop2.2.0完全分布式集群平台安装与设置-入门级手把手
- 使用函数的多个返回值