MoreEffectiveC++Item35(基础议题)(条款1-4)
条款1:区别指针和引用
条款2:最好使用C++转换操作符
条款3: 绝对不要以多态的方式处理数组
条款4: 避免无用的缺省构造函数
条款1:区别指针和引用
1.指针(pointer) 使用[*/->]
引用(reference) 使用[.]
2.a.引用没有null
b.引用必须初始化
c.引用不可以被重新赋值
3.引用比指针的效率更高(其实只是更安全),引用不需要判定是否为null
总结: 指向不变用引用
条款2:最好使用C++转换操作符
C的强制转换是一定会实现,但是并不保证强转后的结果是否正确.而且可读性差.C++封装了这C的强转并且提高了强转的安全性.
下面简单介绍一下C++的四种强制转换
1.static_cast 用于普通类型的转换(int,char...) [类似于 int const *p 不可以用static_cast<>]
2.const_cast 去除const属性 [eg:const char *pc=" HDU"; char *p=const_cast<char *>(pc);]
3.dynamic_cast 多态之间类型转换 转换指针失败时返回null
转换引用失败时抛出bad_cast
转换类型失败时返回 0
4.reinterpret_cast 指针类型间的转换
条款3: 绝对不要以多态的方式处理数组
class Base{ ... };(size: 4)// 假设大小为4
class Driver: public BASE{ ... };(size: 6)//子类一般会比父类多一些data 所以一般的子类都会比父类大一些
void printArray(ostream& s,const Base array[],int numElements){
{
for (int i = 0; i < numElements; ) {
s << array[i];
}
}
如果用 Base BaseArray[10] 调用该函数 会正常运行
如果用 Driver DriverArray[10] 去调用该函数 会通过编译 但是后果却不可预估
我们仔细想一想 array[i]代表的意义是 *(array + i) 它的步长是 i*sizeof(数组中的对象) 在该函数 步长为4
BaseArray它的大小是4 可以正常调用此函数 然而DriverArray的步长是6 循环后会造成一种不可预估的错误
条款4: 避免无用的缺省构造函数
不提供默认构造函数是为了防止创建出无意义的类
class Person{
public:
Person(int IDCard);
...
};
由于Person缺少默认构造函数,其运行时可能在3种情况下出错
1.创建数组时
Person person[]; //错误无法调用正确的默认构造函数
Person * person = new Person[];//错误 同上
解决方案:
a:
int ID1,ID2,ID3,ID4...ID10
Person person[] = {
person(ID1),
person(ID2),
...
Person()}// 使用non-heap数组 缺点:无法延伸至heap数组 创建1000个需初始化1000次
b:
tepedef Person * p;// p是指向Person的一个指针
p array[];
p * array = new p[];
for (int i =; i<;i++)
{
p[i] = new Person[IDCard];
}
//两个缺点手动删除指针,需创建容纳指针的内存,详情见条款8
c:
void *rawMemory =operator new[](*sizeof(Person));
Person *person =static_cast<Person*>(rawMemory);
for (int i = ; i < ; ++i){
new (&person[i]) Person( IDCard);
}
//缺点需以构造顺序相反的顺序析构
for (int i = ; i >= ; --i){
person [i].~Person();
operator delete[](rawMemory);
}
//切记不能使用普通的数组删除法
//delete [] person ;//错误 person 不是new出来的
2.如果该类没有默认构造函数,那么它有可能不适用有些模板。如果类的设计者自定义的类模板(准确的说应该是容器模板)使用内存池的方法的话,这一个缺陷可以避免
3.如果虚基类没有默认构造函数,则每个派生类都必须调用虚基类的构造函数.这个是不被期待的.
MoreEffectiveC++Item35(基础议题)(条款1-4)的更多相关文章
- More Effective C++ 基础议题(条款1-4)总结
More Effective C++ 基础议题(条款1-4)总结 条款1:仔细区别pointers和references 如果有一个变量,其目的是用来指向(代表)另一个对象,但是也有可能它不指向(代表 ...
- MoreEffectiveC++Item35(效率)(条款16-24)
条款16 谨记80-20法则 条款17 考虑使用 lazy evaluation(缓释评估) 条款18 分期摊还预期的计算成本 条款19 了解临时对象的来源 条款20 协助完成"返回值的优化 ...
- MoreEffectiveC++Item35(操作符)(条款5-8)
条款5 对定制的"类型转换函数"保持警惕 条款6 区别increment/decrement操作符的前值和后置形式 条款7 千万不要重载&&,||,和,操作符 条款 ...
- MoreEffectiveC++Item35 条款27: 要求或禁止对象产生于heap中
一 要求对象产生在heap中 阻止对象产生产生在non-heap中最简单的方法是将其构造或析构函数声明在private下,用一个public的函数去调用起构造和析构函数 class UPNumber ...
- MoreEffectiveC++Item35(异常)(条款9-15)
条款9 使用析构函数防止内存泄漏 条款10 在构造函数中防止内存泄漏 条款11 禁止异常信息传递到析构函数外 条款12 理解"抛出一个异常''与"传递一个参数"或调用一个 ...
- MoreEffectiveC++Item35 条款26: 限制某个class所能产生的对象个数
一 允许零个或一个对象 我们知道每当即将产生一个对象,我们有一个constructor被调用,那么我们现在想组织某个对象的产生,最简单的方法就是将其构造函数声明成private(这样做同事防止了这个类 ...
- MoreEffectiveC++Item35 条款25 将constructor和non-member functions虚化
1.virtual constructor 在语法上是不可将构造函数声明成虚函数,虚函数用于实现"因类型而异的行为",也就是根据指针或引用所绑定对象的动态类型而调用不同实体.现在所 ...
- ###《More Effective C++》- 基础议题
More Effective C++ #@author: gr #@date: 2015-05-11 #@email: forgerui@gmail.com 一.仔细区别pointers和refere ...
- More Effective C++ - 章节一 : 基础议题
1. 仔细区分 pointers 和 references references和pointers的差别描述如下: pointer:当需要考虑"不指向任何对象"时,或者是考虑&qu ...
随机推荐
- oracle 分区表详解
一.分区表的概述: Oracle的表分区功能通过改善可管理性.性能和可用性,从而为各式应用程序带来了极大的好处.通常,分区可以使某些查询以及维护操作的性能大大提高.此外,分区还可以极大简化常见的管理任 ...
- GRUB2 分析 (四)
接上一篇 kernel.img由startup.S以及一堆c文件编译而成.这是一个ELF格式的文件.(其实前面的boot.img. diskboot.img.lzma_decompress.img本来 ...
- SQL学习笔记之MySQL中真假“utf8” 问题
0x00 MySQL中UTF8报错 最近我遇到了一个 bug,我试着通过 Rails 在以“utf8”编码的 MariaDB 中保存一个 UTF-8 字符串,然后出现了一个离奇的错误: Incorre ...
- Swoole学习(四)Swoole之简单WEB服务器的创建
环境:Centos6.4,PHP环境:PHP7 <?php //创建WEB服务器 $host = '0.0.0.0'; $port = ; $server = new swoole_http_s ...
- 20145313 《Java程序设计》第十周学习总结
网络编程 网络编程就是在两个或两个以上的设备(例如计算机)之间传输数据.程序员所作的事情就是把数据发送到指定的位置,或者接收到指定的数据,这个就是狭义的网络编程范畴.在发送和接收数据时,大部分的程序设 ...
- python-内置函数及捕获异常
eval:把字符串转换成有效表达式 repr:把有效表达式转换成字符串 round(...) round(number[, ndigits]) -> number Round a num ...
- openwrt的编译系统在哪里对程序进行开机自动启动配置
答:在include/rootfs.mk里的宏prepare_rootfs中进行的
- [BZOJ2688]折线统计
Description 二维平面上有n个点(xi, yi),现在这些点中取若干点构成一个集合S,对它们按照x坐标排序,顺次连接,将会构成一些连续上升.下降的折线,设其数量为f(S).如下图中,1-&g ...
- [BZOJ3124]直径
Description 小Q最近学习了一些图论知识.根据课本,有如下定义.树:无回路且连通的无向图,每条边都有正整数的权值来表示其长度.如果一棵树有N个节点,可以证明其有且仅有N-1 条边. 路径:一 ...
- ADO.NET 使用DELETE语句批量删除操作,提示超时,删除失败,几种优化解决思路
起因是如此简单的一句sql 提示:Timeout 时间已到.在操作完成之前超时时间已过或服务器未响应. 提供几种解决思路: 1.检查WHERE条件中字段是否已建索引 2.检查是否被其他表引用,引用表外 ...