zoukankan      html  css  js  c++  java
  • Effective C++ 精要(第六部分:继承与面向对象设计)

    条款32:确定你的public继承塑模出is-a关系


    条款33:避免遮掩继承而来的名称

    name hiding其实是和作用域有关的话题, 但是它在继承体系中有些更微妙的东西。我们知道在一个函数中如果有个local 变量x,同时函数外还有个变量x,那在这个函数中看到的x是函数内的local变量x。也就是local变量hide了全局变量,这个是C语言中的name hiding。下面看继承时的情况,其实从编译器的角度看,就是Base类的作用域比子类的要大,当在子类中定义了一个symbol时,会hide基类中同名的symbol。我们这里说symbol就是说它无关于这个symbol是什么类型,int?double?virtual函数?non-virtual函数?都无所谓的,关键就是看其名字是不是一样的。

    image

    为了更好的说明这个问题,看下面的图:

    image

    子类中的mf1会遮盖掉在基类中的mf1,包括那个带int参数的;mf3会遮盖基类中的mf3,是的,两个都被遮盖了。如果我们想把所有名为mf1的声明式都带到子类中,可以在子类中使用using Base::mf1,这时就所有的mf1就在子类中可见,并且为public。但如果你只是想把某一个名为mf3的函数带到子类中,其他就不想这样做,比如在private继承时,我们唯一想继承的是某个版本的mf3,我们可以使用一个forwarding函数来做这个事情。

    条款34:区分接口继承和实现继承

    说到继承,我们可能会想做的事情包括:希望子类只继承基类的接口;有时希望子类同时继承接口和实现,但又希望能override它们所继承的实现;而有时候你希望子类继承基类的接口和实现,并且不允许override任何东西。

    • 如果是只继承接口,可以把基类中的函数做成纯虚函数,我们可以为纯虚函数提供一份实现代码;
    • 如果是同时继承接口和缺省实现,就应该选用impure virtual函数;【但允许impure virtual函数同时提供接口和缺省实现,会造成问题,比如书中例子,飞机A和B继承了基类的默认fly(),但是新进的机型C的fly()应该有不同的实现,但因为匆忙而没有实现,这时C就会使用基类的默认实现,这会引起灾难的,解决的办法有几个:1. 将fly接口仍然设计成纯虚函数,同时提供一个non-virtual 的protected函数提供缺省实现defaultFly(),强制要求子类实现fly(),如果子类使用缺省实现,就可以直接调用defaultFly(),而如果不用缺省实现,就可以另外实现,因为fly()是纯虚函数,客户必须实现,从而避免了出错的可能性。2. 利用纯虚函数可以有一份实现代码这个特点,在子类的实现中调用父类的缺省实现,或者额外实现】
    • 如果要子类继承函数的接口和一份强制实现,并不允许override,可以声明为一个non-virtual函数。non-virtual函数的意义是不变性凌驾于特异性。


    条款35:考虑virtual函数以外的其他选择

    除了virtual函数,还有其他方式实现多态。比如NVI、Function Pointer和tr1::function。

    • NVI方式是,定义一个non-virtual public成员函数,这个成员函数调用private virtual函数(为什么是private virtual呢?private是因为这份实现不希望被子类继承,virtual是因为,当对子类对象调用non-virtual public函数时,该函数调用的private virtual函数是子类实现的函数,也就是多态了);
    • function Pointer方式:用一个function Pointer作为参数传给类的构造函数,类之后使用这个function Pointer执行某个动作;
    • tr1::function:类似于function Pointer的方式,不过tr1::function更加强大,可以有更多灵活性;
      条款36:绝不重新定义继承而来的non-virtual函数


    条款37:绝不重新定义继承而来的缺省参数值

    virtual函数的缺省参数值是静态绑定的,重新定义只会造成混乱。


    条款38:通过复合塑模出has-a或"根据某物实现出"


    条款39:明智而审慎地使用private继承


    条款40:明智而审慎地使用多重继承

  • 相关阅读:
    使用 asp.net mvc和 jQuery UI 控件包
    ServiceStack.Redis 使用教程
    HTC T8878刷机手册
    Entity Framework CodeFirst 文章汇集
    2011年Mono发展历程
    日志管理实用程序LogExpert
    使用 NuGet 管理项目库
    WCF 4.0路由服务Routing Service
    精进不休 .NET 4.0 (1) asp.net 4.0 新特性之web.config的改进, ViewStateMode, ClientIDMode, EnablePersistedSelection, 控件的其它一些改进
    精进不休 .NET 4.0 (7) ADO.NET Entity Framework 4.0 新特性
  • 原文地址:https://www.cnblogs.com/whyandinside/p/2755070.html
Copyright © 2011-2022 走看看