最近重新捧起了《Effective c++》,其中味道又有不同,这里记录之。。。

  这篇文章记录一下public继承的知识点...

(1)public继承的意义
  该继承方式是代表is-a(是一种)的关系,即施加于基类的所有操作,同样能施加于派生类;换句换说,比如存在类A(person)和类B(student),且类B以public的方式继承于类A,那么可以说类B对象也是类A对象的一种,那么能施加于类A(person)的操作(比如eat),必然能施加于类B上;如果不满足这种关系,就不能用public继承,而需要考虑其他设计,来约束这两个类之间的关系。以上就是public继承的意义之所在,明白这个意义能够指导,能否直接将一个object以public的方式继承于另一个object!!!
(2)public继承的实质
  在设计继承体系时,对于函数属性的设置往往令人头痛,到底是设置为virtual还是non-virtual呢,有时还会因为是否将一个类设为abstract class而耿耿于怀,以上这些问题的出现,表示我们还没有弄明白继承体系中,这些属性设置的真正含义之所在。这里还要记录一下public继承自身的特点,即父类中public属性的成员(成员函数和成员变量)被子类继承后,依然是public属性;private属性和protected属性以此类推。
下面就一个例子来说明public继承的实质:

 class A{
public:
//...(省略构造函数和析构函数)
virtual void pureVirFunc() const = ;
virtual void virFunc() const;
void nonVirFunc() const;
private:
//...(省略成员变量)
};

上述类A定义了三个成员函数,代表三种属性的函数,即纯虚函数,非纯虚函数和非虚函数;这三种函数在继承时有着各自的行为,这些行为代表着继承的实质。

 class B : public A{
public:
//...(省略构造函数和析构函数)
virtual void pureVirFunc() const;
virtual void virFunc() const;
// 对于类A中的nonVirFunc函数,这里
// 不能重写
private:
//...
};

简单阐述三种函数继承时的行为:
1.纯虚函数——类A将pureVirFunc设置为纯虚函数,表明类A是一个abstract class,它不能产生具体的对象,肆意去生成类A的对象的行为是愚蠢的,但能够声明它的指针,用其指针指向具体的派生类对象,达到动态绑定的效果,如此:
----------------------------------------------------
A a; //错误,不能为abstract class生成具体对象
A* pa = new B();//正确
pa->virFunc(); //动态绑定,调用的是类B的函数
----------------------------------------------------
类A将pureVirFunc设置为纯虚函数,以此来告知各位子类(以public的方式继承于类A),对于该函数对应的行为,它只是声明函数接口(子类们也只能继承该接口的声明),具体如何实现那是子类们自己的事情。当然,C++也给予那些多事的abstract class一个方便——能为纯虚函数提供显示的定义;但是,由于子类必须重写纯虚函数(不然,子类也是abstract class),这样看来,abstract基类为纯虚函数提供显示定义似乎没有必要,因为子类根本用不上。的确,除了用来耍酷,一般是用不上的,不过,《Effective c++》中阐述了一种情况,为纯虚函数提供显示定义的行为是有必要。
2.非纯虚函数——较之纯虚函数,一般的虚函数更常用,毕竟大部分对象时具体的,就应该能让它们产生对象;父类赋予某个函数的属性为impure virtual时,一般会附带默认的实现,该情况对应上面例子中的virFunc函数,即告知其子类,该行为对应的函数,它提供了函数接口声明,并附上其默认实现,如果默认实现能完成某个子类的需要的功能,那么该子类直接继承而不需重写该函数;不然,就需要重写该函数,来满足自己的需求。大部分情况下,子类对于父类提供的默认实现都不太满意,会重写继承而来的impure virtual函数,以此来体现继承体系中的多态性。
3.非虚函数——如果父类将某个行为定义为非虚函数,该情况对应上面例子中的nonVirFunc函数,即告知各位子类,它提供了该行为对应的函数接口声明和必要的实现,并且该函数的实现能满足子类的需求(即便以后发生其他变化),它不希望子类们自以为是的去重写这类函数。反过来想,如果父类提供的实现不能满足子类未来的需求,那就应该将该函数声明为虚函数而不是非虚函数了,对吧?

c++学习_1的更多相关文章

  1. 数塔~~dp学习_1

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2084 数塔 Time Limit: 1000/1000 MS (Java/Others)    Mem ...

  2. linux驱动学习_1

    目前项目需要,需要做linux驱动了,记录一下 学习驱动,大家一定都会写一个hello world代码,网上也有很多范例,但是记录一下遇到的问题. 1.make之后,使用insmod加载,终端没有打印 ...

  3. Linux下C编程的学习_1

    0x0:为什么写这个系列的文章 博客原本的定位是安卓游戏的破解,可是为什么写这系列的文章呢? 由于在破解过程中,我们是无法避免来敲代码的,恢复算法,模拟算法,游戏中对数据的解密.游戏中对保存在clie ...

  4. Verilog HDL学习_1:分频器/PWM的实现

    (一)参考学习资料 (二)实际操作 1. 相关变量计算:   First Initial Second Initial Upper case H X ASCII (Dec) 72 88 Lengths ...

  5. 《windows程序设计》学习_1:初识windows程序

    #include<windows.h> int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szC ...

  6. python学习_1

    1.python2和python3 从宏观上讲,python2源码不标准.混乱.重复,和龟叔的理念背道而驰. 在python3上,实现了源码的统一化和标准化,去除了重复的代码. 2.编译型语言和解释型 ...

  7. 【转】PCA算法学习_1(OpenCV中PCA实现人脸降维)

    前言: PCA是大家经常用来减少数据集的维数,同时保留数据集中对方差贡献最大的特征来达到简化数据集的目的.本文通过使用PCA来提取人脸中的特征脸这个例子,来熟悉下在oepncv中怎样使用PCA这个类. ...

  8. Tensorflow_入门学习_1

    1.0 TensorFlow graphs Tensorflow是基于graph based computation: 如: a=(b+c)∗(c+2) 可分解为 d=b+c e=c+2 a=d∗e ...

  9. 6-网页,网站,微信公众号基础入门(PHP学习_1)

    https://www.cnblogs.com/yangfengwu/p/11037675.html 安装PhpStrom http://www.jetbrains.com/phpstorm/ 然后百 ...

随机推荐

  1. HBase的安装与使用

    1.安装 由于还是学习阶段,所以没有在生产环境练习,就在本地建了个虚拟机进行HBase的安装. 下载地址http://www.apache.org/dyn/closer.cgi/hbase/,选择一个 ...

  2. 解决lucene 重复索引的问题

    在使用Lucene过程中,会发现当我们为添加新的Document时,会产生重复现象(两次添加同一个Document),毕竟Lucene中没有像数据库中一样,有键可以区分.不过我们可以通过为Docume ...

  3. 【BZOJ】3309: DZY Loves Math 莫比乌斯反演优化

    3309: DZY Loves Math Description 对于正整数n,定义f(n)为n所含质因子的最大幂指数.例如f(1960)=f(2^3 * 5^1 * 7^2)=3, f(10007) ...

  4. 我的第一个python代码实践:Trie树

    Trie树 不解析,  本园很多博文有提到. 直接上代码: #coding:utf-8 ''' create on 2013-07-30 @author :HuangYanQiang ''' LETT ...

  5. linq query, using int.parse to convert varchar to int while orderby

    var t = from x in context.NewsLetterItem.ToList() //add .ToList at this place where x.APPId == appid ...

  6. JavaScript decodeURI() 和 encodeURI() 函数

    定义和用法 decodeURI() 函数可对 encodeURI() 函数编码过的 URI 进行解码. 语法 decodeURI(URIstring) 参数 描述 URIstring 必需.一个字符串 ...

  7. noj [1479] How many (01背包||DP||DFS)

    http://ac.nbutoj.com/Problem/view.xhtml?id=1479 [1479] How many 时间限制: 1000 ms 内存限制: 65535 K 问题描述 The ...

  8. 什么是 DevSecOps?系列(一)

    什么是 DevSecOps? 「DevSecOps」 的作用和意义建立在「每个人都对安全负责」的理念之上,其目标是在不影响安全需求的情况下快速的执行安全决策,将决策传递至拥有最高级别环境信息的人员. ...

  9. cocos-html5 JS 写法基础 语言核心

    转载:http://blog.csdn.net/leasystu/article/details/18735797 cocos2dx 3.0 js继承:John Resiq的继承写法解析 CCClas ...

  10. [jobdu]二进制中1的个数

    做法是n&(n-1).据说还有变态的查表法:http://www.cnblogs.com/graphics/archive/2010/06/21/1752421.html.最后,居然必须用sc ...