Chinaunix首页 | 论坛 | 博客
  • 博客访问: 5764000
  • 博文数量: 291
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 7924
  • 用 户 组: 普通用户
  • 注册时间: 2016-07-06 14:28
个人简介

阿里巴巴是个快乐的青年

文章分类

全部博文(291)

文章存档

2018年(21)

2017年(4)

2016年(5)

2015年(17)

2014年(68)

2013年(174)

2012年(2)

分类: C/C++

2013-07-03 14:39:20

一、public继承       
        ”public继承“意味着is-a,即适用于base class身上的每一件事情一定也适用于derived class身上,因为每一个derived class对象也都是一个base class对象。

二、避免遮掩继承而来的名称
        derived class内的名称会遮掩base class内的名称,在public继承下从来没有人希望如此。为了让被遮掩的名称再见天日,可使用using声明式。
        举例说明如下:
        class Base {
        public:
                virtual void mf() = 0;
                virtual void mf(int i);
        };
        class Derived : public Base {
        public:
                virtual void mf();
        };
        Derived d;
        int x;
        d.mf();         //没问题,调用Derived::mf
        d.mf(x);        //错误,因为Derived::mf遮掩了Base::mf
        class Derived : public Base {
        public:
                using Base::mf;        //让Base class内名为mf的所有东西在Derived作用域内都可见(并且public)

                virtual void mf();
        };
        Derived d;
        int x;
        d.mf();         //没问题,调用Derived::mf
        d.mf(x);        //没问题,调用Base::mf

三、区分接口继承和实现继承
        在public继承之下,derived class总是继承base class的接口。
        pure virtual函数、simple(impure) virtual函数、non-virtual函数之间的差异,使你得以精确指定你想要derived class继承的东西:只继承接口、继承接口和一份缺省实现、继承接口和一份强制实现。

四、不重新定义继承而来的non-virtual函数
        绝不要重新定义继承而来的non-virtual函数,否则违反了基类”不变性凌驾特异性“的性质,如果真要如此应该在基类中定义virtual函数。

五、不重新定义继承而来的缺省参数值
        绝不要重新定义一个继承而来的缺省参数值,因为缺省参数值都是静态绑定,而virtual函数——你唯一应该覆写的东西——却是动态绑定。

六、通过复合朔模出has-a或”根据某物实现出”
        复合是类型之间的一种关系,当某种类型的对象内含它种类型的对象,便是这种关系,例如:
        class Address {...};        //某人地址
        class Person {
        public:
                ...
        private:
                Address address;        //复合成分
                std::string name;
        };
        在应用领域,复合意味着has-a;在实现领域,复合意味着根据某物实现出。

private继承
        private继承遵循如下两条规则:
        (1)编译器不会自动将一个derived class对象转换为一个base class对象。举例如下:
        class Person {...};
        class Student : private Person {...};
        void eat(const Person& p);
        Person p;
        Stduent s;
        eat(s);        //错误,因为父子类之间不是像public继承时一样的is-a的关系
        (2)由private base class继承而来的所有成员,在derived class中都会变成private属性,纵使它们在base class中原本是protected或public属性。
        从实现的角度来说,private继承具有has-a的意义,但跟复合带来的has-a还是有一定的区别的:
        (1)继承时编译器可以进行空基类优化,这点可以参考我的这篇博文《C++之对象大小》,这是其相比复合的优势。
        (2)private继承后可以在derived class中访问base class的protected成员,也可以重新定义其virtual函数,这是其相比复合的优势。
        (3)private继承意味着的derived class对象不能访问base class中的函数,因为变成私有的了,也就是private继承意味着只有实现部分被继承,而接口部分应略去,这是其相比复合的劣势。
        需要注意的是:虽然private继承有时也有一定的优势,但“明智而审慎地使用private继承”是必要的,只有在考虑完所有方案后,发现其仍然是“表现程序内两个class之间关系”的最佳方案时,才使用它。
        
        



阅读(3603) | 评论(13) | 转发(3) |
给主人留下些什么吧!~~

scq2099yt2013-07-03 14:40:09

文明上网,理性发言...