大学的时候学校开了C++的课程,我考的还不错。毕业后就一直搞软件开发,大概一年前开始用VC做项目。最近静下心来看了C++的经典著作《Effective C++ 》,才发现自己的C++水平其实真的很一般!书中提到的有些东西,我竟然从来没有注意过!还有些竟然是我第一次听说!
下面以实例说明(我用我写的更小的例子代替了书中的例子,书中原文我用红色标示)。
1.关于类成员的初始化顺序问题
条款13的标题是:initialization list中的members初始化次序应该和其在class内的声明次序相同。
我不知道大家在用C++开发的时候有没有注意过这个问题,反正我是从来没有往这方面想过!
下面来看例子:
classCMyIntArray
{
public:
CMyIntArray(intlowBound,inthighBound);
size_tGetArraySize()const{returndata.size();};
private:
std::vector<int>data;
size_tsize;
intlBound,hBound;
};
CMyIntArray::CMyIntArray(intlowBound,inthighBound)
:size(highBound-lowBound+ 1)
,lBound(lowBound)
,hBound(highBound)
,data(size)
{
}
如果没有看过这本书,没有任何提示,我想很多搞C++开发的人看不出这简单几行代码有什么问题(当然,编译肯定是不会有问题的)。
可是,如果程序中有类似于下面的代码,问题就会在程序运行的时候爆发出来:
CMyIntArrayoTest(5,13);
cout<<oTest.GetArraySize()<<endl;
而且你就算在debug状态下进行跟踪也很难发现问题的根源所在!
问题处在什么地方呢?就在于成员变量的声明次序上!上面变量声明的次序改为:
size_tsize;
intlBound,hBound;
std::vector<int>data;
问题就可以迎刃而解!
惊奇吗?为什么会这样?书中给出了答案:class members系以它们在class内的声明次序来初始化;和它们在member initialization list中出现的次序完全无关。
上面代码的错误根源是:data在初始化的时候size还没有定义!也就是说要初始化一个没有定义大小的vector,当然会出错。
2.关于“切割问题”
下面是书中的一段话(条款22中):
当一个derived class object被交出去当作一个base class object时,它原本所以“成为一个derived class object”的所有特征,都会被切除(slicing)掉,只留下内部一个base class object。
下面是我写的小例子:
classCBase
{
public:
virtualvoidTest()const{cout<<"OutputfromCBase!"<<endl;};
};
classCDerived:publicCBase
{
public:
virtualvoidTest()const{cout<<"OutputfromCDerived!"<<endl;};
};
下面是两个函数:
voidTest1(CBasetest)
{
test.Test();
}
voidTest2(constCBase&test)
{
test.Test();
}
用下面的代码分别调用函数Test1和Test2:
CDerivedoTest;
Test1(oTest);
Test2(oTest);
问题是:调用函数Test1和函数Test2分别输出什么?
正确答案是:
Output from CBase!
Output from CDerived!
惊奇吗?一点儿也不惊奇!书中已经给出了为什么会这样:以by reference的方式传递参数,有另一个优点:可避免所谓的“切割(slicing)问题”。
3.关于非虚拟函数的静态绑定和虚拟函数的动态绑定
下面是例子:
classCBase
{
public:
virtualvoidTest()const{cout<<"OutputfromCBase!"<<endl;};
};
classCDerived:publicCBase
{
public:
voidTest()const{cout<<"OutputfromCDerived!"<<endl;};
};
现在有下面的代码调用:
CDerivedd;
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.关于缺省值的静态绑定
还是看例子:
classCBase
{
public:
virtualvoidTest(intiTest=0)const=0;
};
classCDerived:publicCBase
{
public:
voidTest(intiTest=1)const{cout<<iTest<<endl;};
};
下面是调用代码:
CBase*p=newCDerived;
p->Test();
我们的本意是想输出1,可是结果却是输出0!
不用惊奇,书中给出了答案:虚拟函数系动态绑定(dynamically bound),而缺省参数值却是静态绑定(statically bound)。
而且,书中的条款38也给了大家忠告:绝对不要重新定义继承而来的缺省参数。
写在最后:其实VC和BCB之类的只能是C++的开发工具,而基础还是C++。就算你的VC和BCB用得再熟练,也是仅仅是对其提供的类库而已,而没有真正领会C++的精髓。这些是我看了这本书后的感想。现在觉得静下心来看了这本书,真是受益匪浅呀。希望这篇文章能给读者一点启发。我的下一个目标就是读C++之父Bjarne Stroustrup的那本经典著作《The C++ Programming Language》。如果我有什么收获,也会在这里给大家分享。
分享到:
相关推荐
Effective C++中文版 2nd Edition Effective C++中文版 2nd Edition Effective C++中文版 2nd Edition
effective c++ 2nd 中文
The C++ Standard Library - A Tutorial and Reference, 2nd Edition describes this library as now incorporated into the new ANSI/ISO C++ language standard (C++11). The book provides comprehensive ...
《C++ Template》第二版,2017年9月16日出版 Templates are among the most powerful features of C++, but they remain misunderstood and underutilized, even as the C++ language and development community ...
An introduction to Design Patterns in C++ with Qt 2nd Edition 中文版 C++ qt 设计模式 第二版, 中英文版 合集 Master C++ “The Qt Way” with Modern Design Patterns and Efficient Reuse This fully ...
Effective C++ Second Edition(中文版),比较经典
Effective C++ Third Edition 55 Specific Ways to Improve Your Programs and Designs 《Effective C++》 第三版改善程序技术与设计思维的55个有效做法
本书阐述C++编程和设计中的很多常见问题及其解法,附有例子代码。
effective c++ 2nd edition中英版 effective c++ 3rd edition中英版 再附一个The C programming Language 都是chm版的,看起来比pdf好多了 有人打开,说看不到内容。那可能是在打开的时候,有“每次打开前提醒”这样...
Effective C++: 50 Specific Ways to Improve Your Programs and Design (2nd Edition) by Scott Meyers Look inside this book List Price: $37.95 Price: $33.78 & This item ships for FREE with Super ...
In C++ Templates, Second Edition, three pioneering C++ experts show why, when, and how to use modern templates to build software that’s cleaner, faster, more efficient, and easier to maintain. ...
The C++ Standard Library - A Tutorial and Reference, 2nd Edition describes this library as now incorporated into the new ANSI/ISO C++ language standard (C++11). The book provides comprehensive ...
The C++ Standard Library: A Tutorial and Reference, Second Edition, describes this library as now incorporated into the new ANSI/ISO C++ language standard (C++11). The book provides comprehensive ...
《C++ Template》第二版,2017年9月16日出版 Templates are among the most powerful features of C++, but they remain misunderstood and underutilized, even as the C++ language and development community ...
06 Effective C++: 50 Specific Ways to Improve Your Programs and Design (2nd Edition) 07 More Effective C++: 35 New Ways to Improve Your Programs and Designs 08 Exceptional C++: 47 Engineering Puzzles,...
The C++ Standard Library: A Tutorial and Reference, Second Edition, describes this library as now incorporated into the new ANSI/ISO C++ language standard (C++11). The book provides comprehensive ...
介紹物件導向軟體工程之書籍
06 Effective C++: 50 Specific Ways to Improve Your Programs and Design (2nd Edition) 07 More Effective C++: 35 New Ways to Improve Your Programs and Designs 08 Exceptional C++: 47 Engineering Puzzles,...
06 Effective C++: 50 Specific Ways to Improve Your Programs and Design (2nd Edition) 07 More Effective C++: 35 New Ways to Improve Your Programs and Designs 08 Exceptional C++: 47 Engineering Puzzles,...
06 Effective C++: 50 Specific Ways to Improve Your Programs and Design (2nd Edition) 07 More Effective C++: 35 New Ways to Improve Your Programs and Designs 08 Exceptional C++: 47 Engineering Puzzles,...