设为首页 加入收藏

TOP

Effective C++读书笔记(条款24-29)(二)
2015-07-20 17:17:53 来源: 作者: 【 】 浏览:18
Tags:Effective 读书 笔记 条款 24-29
plates全特化是好的,但千万不要在std内加入一些对于std
来说全新的东西,因为C++标准委员会禁止加入那些已经声明好的东西,即便通过了
编译和执行,其行为也不能得到明确。
____________________________________________________________________________________________________________________________________

(五).实现

____________________________________________________________________________________________________________________________________

条款26:尽可能延后变量定义式的出现时间
#1.尽可能延后变量定义式的出现,如果可以,要直到初始化为止。
理由1:增加程序的可读性,使程序结构更清晰。
理由2:对于用户(或系统)定义类型,过早的定义变量,可能会导致程序在抛出异常,
函数返回等情况下变量没有使用,因此会带来额外的构造和析构成本。
(内置类型的定义,可以用C风格初始化,也可以延迟变量定义时间,为了统一起见,
最好延迟变量定义的时间。)
例如:
std::string encryptPassword(const std::string& password)
{
    using namespace std;
    string encrypted;
    if(password.length() < MinimumPasswordLength)
        throw logic_error("Password is too short");
    ...
    
    return encrypted;
}
//若抛出logic_error异常,encrypted完全未被使用。
//所以应改为:
std::string encryptPassword(const std::string& password)
{
    
    if(password.length() < MinimumPasswordLength)
        throw logic_error("Password is too short");
    using namespace std;
    string encrypted(password);
    ...
    return encrypted;
}

#2.方法A和方法B的定义方式各有千秋,如果你知道赋值的成本比“构造+析构”的成本低,
并且注重效率,那么你应该使用方法A。否则,为了保证程序的可读性和易维护性,
你应该使用方法B。
//方法A:定义于循环外
Widget w;
for(int i=0;i
  
   ____________________________________________________________________________________________________________________________________
   
条款27:尽量少做转型动作
#1.const_cast,dynamic_cast,reinterpret_cast,static_cast转型操作符。
const_cast:常量性转除,唯一有此能力的C++-style转型操作符。
dynamic_cast:主要用来执行”安全向下转型“,也就是用来决定某对象是否归属
于继承体系中的某个类型。它是唯一无法由旧式语句执行的动作,也是唯一可能
耗费重大运行成本的转型动作。
reinterpret_cast:意图执行低级转型,实际动作(及结果)可能取决于编译器,
这也表示它不可移植,例如将一个 pointer to int 转型为一个 int。这一类
转型在低级代码以为很少见。
static_cast:强迫隐式转换,例如
将 non-contst 转型为 const,
将 int 转型为 double,
将 void*指针与 typed指针互转,
将 pointer-to-base 与 pointer-to-derived互转,
但无法将 const 转型为 non-const,因为这个只有const_cast办的到。

#2.如果可以,尽量避免转型,特别是在注重效率的代码中避免dynamic_cast,如果
有个设计需要转型动作,试着发展无需转型的替代设计。
理由1:C++规则的设计目标之一是,保证“类型错误”绝不发生,为避免在任何对象

身上执行不安全,荒谬的操作,请尽量避免转型。

理由2:任何一个类型转换往往令编译器编译出运行期间执行的码,例如:

class Base{...};
class Derived:public Base{...};
Derived d;
Base* pb = &d;
//为获取Base*指针值,在运行期间会有个偏移量(offset)添加在Derived*指针身上,
//编译器会为此额外编译出运行期间执行的码。(注意:这里的offset并不明确,
//因为对象的布局方式和地址计算方式随编译器的不同而不同。)

理由3:dynamic_cast会耗费重大的运行期成本,在深度继承中,单单多次的
”class名称之字符串“的strcmp比较就会耗费一定的效率成本。

【两种避免dynamic_cast转型的替代策略】:
(1).在单一继承中,直接用 derived class 指针替代 base class 接口处理的derived
class 对象,例如:
//假设先Window/SpecialWindow继承体系中只有SpecialWindows才支持闪烁效果,
//试着不要这样做:
class Window {...};
class SpecialWindow:public Window{
public:
    void blink();
    ...
};

typedef std::vector
    
     > VPW;
VPW winPtrs;
...
for(VPW::iterator iter = winPtrs.begin();
    iter != winPtrs.end();++iter){
    if(Specialwindow* psw=dynamic_cast
     
      (iter->get())) psw->blink(); } //应该改成这样: typedef std::vector
      
       > VPW; VPW winPtrs; ... for(VPW::iterator iter = winPtrs.begin(); iter != winPtrs.end();++iter){ (*iter)->blink(); }
      
     
    
(2).多重继承中,用virtual函数代替dynamic_cast所做的事
//用dynamic_cast时如下所示:
class Window {...};
...
typedef std::vector
    
     > VPW;
VPW winPtrs;
...
for(VPW::iterator iter = winPtrs.begin();
    iter != winPtrs.end();++iter){
    if(SpecialWindow* psw1=
        dynamic_cast
     
      (iter->get()))psw1>blink(); else if(SpecialWindow* psw2= dynamic_cast
      
       (iter->get()))psw2->blink(); else if(SpecialWindow* psw3= dynamic_cast
       
        (iter->get()))psw3->blink(); } //以上的做法中有一连串dynamic_cast,这会使产生出来的代码又长又慢, //而且基础不稳,因为继承体系一有改变,所有这一类代码都要检查看看 //是否需要修改,例如添加一个新的derived class,则要在一连串判断 //中加入新的条件分支,及其不易维护。 //所以应该改成这样: class Window { public: virtual void blink(
首页 上一页 1 2 3 4 下一页 尾页 2/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇hdu 5014 贪心+位处理 下一篇POJ3169(最短路+差分约束)

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·怎样用 Python 写一 (2025-12-27 02:49:19)
·如何学习python数据 (2025-12-27 02:49:16)
·想要自学数据分析, (2025-12-27 02:49:14)
·Java 集合框架 - 菜 (2025-12-27 02:19:36)
·Java集合框架最全详 (2025-12-27 02:19:33)