分享
 
 
 

《Effective C++ 中文版 2nd Edition》读后感

王朝c/c++·作者佚名  2006-07-06
窄屏简体版  字體: |||超大  

大学的时候学校开了C++的课程,我考的还不错。毕业后就一直搞软件开发,大概一年前开始用VC做项目。最近静下心来看了C++的经典著作《Effective C++ 》,才发现自己的C++水平其实真的很一般!书中提到的有些东西,我竟然从来没有注意过!还有些竟然是我第一次听说!

下面以实例说明(我用我写的更小的例子代替了书中的例子,书中原文我用红色标示)。

1.关于类成员的初始化顺序问题

条款13的标题是:initialization list中的members初始化次序应该和其在class内的声明次序相同。

我不知道大家在用C++开发的时候有没有注意过这个问题,反正我是从来没有往这方面想过!

下面来看例子:

class CMyIntArray

{

public:

CMyIntArray(int lowBound, int highBound);

size_t GetArraySize() const { return data.size(); };

private:

std::vector<int> data;

size_t size;

int lBound, hBound;

};

CMyIntArray::CMyIntArray(int lowBound, int highBound)

: size(highBound - lowBound +1)

, lBound(lowBound)

, hBound(highBound)

, data(size)

{

}

如果没有看过这本书,没有任何提示,我想很多搞C++开发的人看不出这简单几行代码有什么问题(当然,编译肯定是不会有问题的)。

可是,如果程序中有类似于下面的代码,问题就会在程序运行的时候爆发出来:

CMyIntArray oTest(5, 13);

cout << oTest.GetArraySize() << endl;

而且你就算在debug状态下进行跟踪也很难发现问题的根源所在!

问题处在什么地方呢?就在于成员变量的声明次序上!上面变量声明的次序改为:

size_t size;

int lBound, hBound;

std::vector<int> data;

问题就可以迎刃而解!

惊奇吗?为什么会这样?书中给出了答案:class members系以它们在class内的声明次序来初始化;和它们在member initialization list中出现的次序完全无关。

上面代码的错误根源是:data在得到size之前就已经初始化了,也就是说data的大小是不确定的,调用它的size方法当然会出错!

2.关于“切割问题”

下面是书中的一段话(条款22中):

当一个derived class object被交出去当作一个base class object时,它原本所以“成为一个derived class object”的所有特征,都会被切除(slicing)掉,只留下内部一个base class object。

下面是我写的小例子:

class CBase

{

public:

virtual void Test() const { cout << "Output from CBase!" << endl; };

};

class CDerived : public CBase

{

public:

virtual void Test() const { cout << "Output from CDerived!" << endl; };

};

下面是两个函数:

void Test1(CBase test)

{

test.Test();

}

void Test2(const CBase& test)

{

test.Test();

}

用下面的代码分别调用函数Test1和Test2:

CDerived oTest;

Test1(oTest);

Test2(oTest);

问题是:调用函数Test1和函数Test2分别输出什么?

正确答案是:

Output from CBase!

Output from CDerived!

惊奇吗?一点儿也不惊奇!书中已经给出了为什么会这样:以by reference的方式传递参数,有另一个优点:可避免所谓的“切割(slicing)问题”。

3.关于非虚拟函数的静态绑定和虚拟函数的动态绑定

下面是例子:

class CBase

{

public:

virtual void Test() const { cout << "Output from CBase!" << endl; };

};

class CDerived : public CBase

{

public:

void Test() const { cout << "Output from CDerived!" << endl; };

};

现在有下面的代码调用:

CDerived d;

CBase *pB = &d;

pB->Test();

CDerived *pD = &d;

pD->Test();

输出是:

Output from CDerived!

Output from CDerived!

这个大家应该都知道为什么。可是,如果把CBase的Test方法前的virtual去掉,结果就变了!输出就是:

Output from CBase!

Output from CDerived!

这时,有些人就会奇怪了,pB和pD指向的都是d,为什么会这样输出呢?

答案就是:非虚拟函数是静态绑定的,虚拟函数是动态绑定的。

书中的条款37给了大家忠告:绝对不要重新定义继承而来的非虚拟函数。

4.关于缺省值的静态绑定

还是看例子:

class CBase

{

public:

virtual void Test(int iTest = 0) const = 0;

};

class CDerived : public CBase

{

public:

void Test(int iTest = 1) const { cout << iTest << endl; };

};

下面是调用代码:

CBase *p = new CDerived;

p->Test();

我们的本意是想输出1,可是结果却是输出0!

不用惊奇,书中给出了答案:虚拟函数系动态绑定(dynamically bound),而缺省参数值却是静态绑定(statically bound)。

而且,书中的条款38也给了大家忠告:绝对不要重新定义继承而来的缺省参数。

写在最后:其实VC和BCB之类的只能是C++的开发工具,而基础还是C++。就算你的VC和BCB用得再熟练,也是仅仅是对其提供的类库而已,而没有真正领会C++的精髓。这些是我看了这本书后的感想。现在觉得静下心来看了这本书,真是受益匪浅呀。希望这篇文章能给读者一点启发。我的下一个目标就是读C++之父Bjarne Stroustrup的那本经典著作《The C++ Programming Language》。如果我有什么收获,也会在这里给大家分享。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有