effective C++ 读后感(一) 视C++为一个语言联邦
来源:互联网 发布:淘宝网蓝牙耳机 编辑:程序博客网 时间:2024/06/05 08:36
最近在读effective C++, 有些感想。这本书对于熟悉C++语法,并且想用C++进行开发的程序员有很好的指导意义。书中一共提出了改善程序与设计的55个具体做法,每一点都值得细细琢磨推敲。从这之后的几篇博文将针对每一点结合例子谈谈自己的一些想法。欢迎大家指正。
1.视C++为一个语言联邦
我们都知道,C++是C的一个超集,它与C是兼容的,所以它既支持过程形式,也支持面向对象形式。在我们学C++泛型的时候,会觉得泛型确实给C++提供了更强大的功能,但似乎于面向对象又不是那么紧密。学习标准模板库也会有这样的感觉。
事实上, 我们可以把C++看成一个同四种语言组成的联邦:
1.C 这是最原始的。像int, double, char第基本数据类型,还有数组、指针等都属于这一块。C的目标是高效,所以很多时候为了速度而放弃了异常检查(如数组越界)。
2. Object-Oriented C++。包括类、封装、继承、多态等特性,这个大家也比较熟悉,所以在此不再赘述。
3.Template C++。 就是泛型部分。这属于一种新的编程泛型,叫模板元编程。C++的泛型是非常强大的,以后有时间的话我会将其与Java的泛型来进行比较。虽然模板元编程也是使用泛型,但其实模板元编程与泛型编程还是有差别的。模板元编程注重将很多工作从运行阶段移到了编译阶段。大家有兴趣的话可以参看一下http://blog.csdn.net/ugg/article/details/2703326里举的用泛型计算阶乘的例子。
4. STL。 这是一个Template程序库。它将容器、迭代器、算法和函数对象很好地整合起来了,所以也单独列出来。
有了这个概念,我们在考虑一些编程规则时,就应该结合当前所处的“语言”环境还进行选择了。比如说,在C中,传值一般比传引用要高效。因为传值基本上就是复制内存单元,传引用的话类似传了一个指针,获取值的话还需要借助引用去相应地址地查找。而在Object-Oriented C++中就不是这样了,因为对象传值的话会执行相应的构造函数和析构函数,这时传引用就会比传值要高效了。
下面举一个例子来说明在Object-Oriented C++中传引用比传参数要高效:
#include <iostream>using namespace std;class A {public:A() {}A(A &a) {cout << "get in A's copy constructor\n";}~A() {cout << "get in A's distructor\n";}void print() {cout << "this is A\n";}};void test(A a) {a.print();}int main() {A a;test(a);}
在这个例子中,我们定义了一个类A,它有一个print方法。有一个函数test以A为参数,调用其print方法。
其中我们在调用test时传的是值,这时运行结果为:
get in A's copy constructorthis is Aget in A's distructorget in A's distructor
可以发现在传参时,会另外生成一个对象,调用其复制构造函数,函数结束后,又会调用其析构函数。这样显然效率就低了。
如果把test函数改成传引用:
void test(A &a) {a.print();}
则运行结果为:
this is Aget in A's distructor
有些时候,如果程序编写不够细致的话,传值可能会导致程序崩溃。我们看下面的例子:
#include <iostream>#include <cstring>using namespace std;class A {char *r;public:A(char *b) {int n = strlen(b);r = new char[n + 1];memcpy(r, b, sizeof b);}void print() {cout << r << endl;}~A() {delete[] r;}};void test(A a) {a.print();}int main() {char b[] = "abc";A a(b);test(a);return 0;}
看似没什么问题,在类A中只定义了一个构造函数,为r申了一块存储空间,然后在析构函数中将其释放了。但运行之后会发现会出现“double free or corruption”的错误。原来,是我在类A中忽略了复制构造函数。利用默认的复制构造函数传值时,参数对象的r指针与main函数中a的r指针指向的是同一块地址,导致这一块地址被释放了两次(第一次在test函数返回后,第二次出现在main函数完成之后。从而出错。而如果将传给test的参数改为引用的话,就不会出现这种错误。当然,还是得承认造成这种错误主要还是没有重写复制构造函数(事实上如果没有重载“=”运算,也有可以出现这种错误)。但我们不得不承认,传引用会更安全。
- effective C++ 读后感(一) 视C++为一个语言联邦
- 《Effective C++》读后总结(一)视C++为一个语言联邦
- [Effective C++] 条款01:视C++为一个语言联邦
- effective C++(第三版)读书笔记一——条款一:视C++为一个语言联邦
- 重读经典-《Effective C++》Item1:视C++为一个语言联邦
- 《Effective C++》学习笔记条款01 视C++为一个语言联邦
- 菜鸟读《Effective C++》条款1:视C++为一个语言联邦
- Effective c++ 学习笔记之条款一视C++为一个语言联邦
- Effective C++ 01 视C++为一个语言联邦 笔记
- Effective c++ 笔记—视c++ 为一个语言联邦
- effective c++条款1:视C++为一个语言联邦
- Effective C++ Item 01-视C++为一个语言联邦
- effective C++ 01_视C++为一个语言联邦
- effective C++读书笔记 条款一 视C++为语言联邦
- 条款1 视c++为一个语言联邦(如何理解c++)
- 《Effect C++》学习------条款1 视C++为一个语言联邦
- 条款一:视C++为一个语言联邦
- Effective c++ 学习笔记——之条款1:视C++为一个语言联邦
- 【实用随记】delete动画回调
- php 发送请求的三种方式
- iptables DNAT详解
- 手机误删的通话记录要怎么恢复
- 二维数组中的查找
- effective C++ 读后感(一) 视C++为一个语言联邦
- ZOJ 3560 Re: the Princess 高斯消元
- mac 使用vim,一键安装的工具 janus
- UTF-8编码规则
- Cocos2d学习之路三(使用Zwoptex创建精灵表单和CCAnimate动画)
- 解密回文——栈
- java中判断字符串是否为数字的三种方法
- Android SDK for linux 设置代理
- testlin配合wampserver安装过程记录及问题解决