//1.面向对象程序设计的核心思想是数据抽象,继承,动态绑定。
// 通过使用数据抽象,我们可以将类的接口和实现分离
// 使用继承,可以定义相似的类型并对其相似关系建模
// 使用动态绑定,可以在一定程度上忽视相似类型的区别,而以统一的方式使用它们的对象。 //2.对于某些函数,基类希望它的派生类各自定义适合自身的版本,此时基类就将这些函数声明为虚函数。
// 使用基类的引用或指针调用一个虚函数的时候,将发生动态绑定:根据指针或引用指向的对象类型来调用基类或者派生类的虚函数。
// 基类通常定义一个虚析构函数,以便于对象的正常析构
// 任何构造函数之外的非静态函数都可以是虚函数。在基类中的虚函数,在派生类中隐式的也是虚函数。
// 成员函数如果没有被声明为虚函数,则其解析过程发生在编译时而非运行时。
// 每个类控制自己成员的初始化过程,派生类也最好使用基类的构造函数来初始化它的基类部分 //3.可以将基类的指针或引用绑定到派生类对象上有一层极为重要的含义:当使用基类类型的指针或引用的时候,实际上不清楚其所绑定对象的真实类型。
// 派生类向基类的转换只对指针和引用类型有效,在派生类类型和基类类型之间不存在这样的转换。 //4.智能指针类也支持派生类向基类的转换,这意味着可以将派生类的对象的指针存储在一个基类的智能指针内。 //5.一个派生类如果要覆盖而非隐藏某个继承的虚函数,则它的形参类型必须和被覆盖的虚函数完全一致。
// 同样的,它们的返回类型也必须一致。对于这个规则有一个例外:当此函数返回其类类型的指针或引用时,并且子类向父类类型转换时可访问的时候,它们可以返回各自的类类型。 //6.虚函数也可以有默认实参,但是如果某次函数调用使用了默认实参,则该实参值由本次调用的静态类型决定。所以虚函数最好不用默认实参,或者在子类和基类中使用相同的默认实参。
// 通过作用域运算符,可以实现对虚函数的调用不进行动态绑定。 //7.抽象基类:
// A:和普通的虚函数不同,一个纯虚函数可以没有定义,通过在函数体的位置书写=0就可以将一个虚函数声明为纯虚函数,=0只能出现在类内部虚函数声明处。
// B:也可以为纯虚函数提供定义,但是必须是在类的外部。
// C:不能定义抽象基类的对象,当抽象基类的派生类没有覆盖纯虚函数时,此派生类也不能定义对象。 //8.派生类的构造函数只初始化它的直接基类。各个类控制其对象的初始化过程。 //9.派生类向基类转换的可访问性:
// A:只有当D公有的继承B时,用户代码才能使用派生类向基类的转换。
// B:不论D以任何方式继承B,D的成员函数和友员都能使用派生类向基类的转换。
// C:如果D继承B的方式是公有的或受保护的,则D类的派生类的成员和友员可以使用D向B的类型转换。
// 总结:对于代码中的某个节点来说:如果基类的公有成员是可访问的,则派生类向基类的转换也是可使用的,反之则不行。 //10.就像友员关系不能传递一样,友员关系同样不能继承。基类的友员在访问派生类成员时不具有特殊性,类似的,派生类的友员也不能随意访问基类的成员。 //11.派生类可以为那些可访问的名字提供using声明,以此方法来改变被声明的名字的访问权限(具体权限取决于using声明的位置)。
class CA {protected: int value;};
class CB : public CA {public: using CA::value;}; //则value在CB类中的访问权限是public的 //12.struct和class的唯一区别在于:默认成员访问说明符及默认派生访问说明符的区别,前者均为公有,后者均为私有。 //13.每个类定义了自己的作用域。当存在继承关系时,派生类的作用域嵌套在其基类的作用域中。当一个名字在派生类的作用域中无法被解析,则编译器将在其外层的基类作用域中进行查找。
// 正是由于上述规定,所以在派生类中才能像使用自己的成员一样使用基类的成员。
// 一个对象、指针、引用的静态类型决定了该对象的哪些成员是可见的。即使静态类型和动态类型可能不一致,但是我们能使用哪些成员仍旧是由其静态类型决定的。 //14.和其它作用域一样,派生类也能重用定义在其直接或间接基类中的名字,此时将发生隐藏,派生类的成员将隐藏同名的基类成员,可以通过作用域运算符来访问被隐藏的成员。
// 由于上述隐藏的规则,派生类可以覆盖其基类的重载虚函数的0个或者全部版本,若非如此将发生隐藏。这样就会显得和繁琐。
// 对于上述问题,一个很好的解决方法是:为重载的成员提供一条using声明语句,这样我们就可以无需覆盖基类中的每一个重载版本。此时派生类只需要定义其特殊的函数语句即可。
class CA
{
public:
virtual void fun(){printf("A_0");}
virtual void fun(int){printf("A_1");}
virtual void fun(char*){printf("A_2");}
};
class CB : public CA
{
public:
using CA::fun; //使基类中的所有fun函数被添加到派生类的作用域中。
void fun(int i){printf("B_1");} //重新定义派生类中特定的虚函数。
}; //15.继承关系对基类拷贝控制最直接的影响就是基类通常应该定义一个虚析构函数来正确的释放对象。
// 基类或派生类的合成拷贝控制成员对类本身的成员依次进行初始化、赋值、销毁的操作,此外这些合成的成员还负责使用直接基类中对应的操作对一个对象的直接基类部分进行相应操作。// 在实际编程过程中,如果基类中没有默认、拷贝、移动构造函数,则派生类一般也不要定义相应的操作,其原因是派生类的基类部分将无法被正确操作。 //16.当我们用一个派生类对象为其基类对象初始化或赋值的时候,只有该派生类对象的基类部分会被拷贝、移动、赋值,它的派生类部分将被忽略掉。

//17.
        A(基类) B(派生类)
公有继承 公有成员 公有成员
        保护成员 保护成员
        私有成员 不可见


保护继承 公有成员 保护成员
        保护成员 保护成员
        私有成员 不可见


私有继承 公有成员 私有成员
        保护成员 私有成员
        私有成员 不可见


一般来说,公有继承时是Is A的关系,私有继承时是Has A的关系

 

C++Primer 第十五章的更多相关文章

  1. C++ Primer Plus学习:第十五章

    第十五章 友元.异常和其他 友元 友元类 表 0-1 class Tv { public: friend class Remote; } Remote类可以使用Tv的数据成员,Remote类在Tv类后 ...

  2. 【C++】《C++ Primer 》第十五章

    第十五章 面向对象程序设计 一.OOP:概述 面向对象程序设计(OOP)的核心思想是数据抽象.继承和动态绑定. 通过使用数据抽象,可以将类的接口和实现分离. 使用继承,可以定义相似的类型并对其相似关系 ...

  3. 15第十五章UDF用户自定义函数(转载)

    15第十五章UDF用户自定义函数 待补上 原文链接 本文由豆约翰博客备份专家远程一键发布

  4. 《Linux命令行与shell脚本编程大全》 第十五章 学习笔记

    第十五章:控制脚本 处理信号 重温Linux信号 信号 名称 描述 1 HUP 挂起 2 INT 中断 3 QUIT 结束运行 9 KILL 无条件终止 11 SEGV 段错误 15 TERM 尽可能 ...

  5. CSS3秘笈复习:十三章&十四章&十五章&十六章&十七章

    第十三章 1.在使用浮动时,源代码的顺序非常重要.浮动元素的HTML必须处在要包围它的元素的HTML之前. 2.清楚浮动: (1).在外围div的底部添加一个清除元素:clear属性可以防止元素包围浮 ...

  6. Gradle 1.12用户指南翻译——第四十五章. 应用程序插件

    本文由CSDN博客貌似掉线翻译,其他章节的翻译请参见: http://blog.csdn.net/column/details/gradle-translation.html 翻译项目请关注Githu ...

  7. Gradle 1.12 翻译——第十五章. 任务详述

    有关其他已翻译的章节请关注Github上的项目:https://github.com/msdx/gradledoc/tree/1.12,或访问:http://gradledoc.qiniudn.com ...

  8. Gradle 1.12用户指南翻译——第二十五章. Scala 插件

    其他章节的翻译请参见: http://blog.csdn.net/column/details/gradle-translation.html 翻译项目请关注Github上的地址: https://g ...

  9. Gradle 1.12用户指南翻译——第三十五章. Sonar 插件

    本文由CSDN博客万一博主翻译,其他章节的翻译请参见: http://blog.csdn.net/column/details/gradle-translation.html 翻译项目请关注Githu ...

随机推荐

  1. Rails--default_scope

    Example: default_scope where("agents.deleted = ?", false)

  2. mysql线程缓存和表缓存

    一.线程缓存1.thread_cache_size定义了线程缓冲中的数量.每个缓存中的线程通常消耗256kb内存2.Threads_cached,可以看到已经建立的线程二.表缓存(table_cach ...

  3. Python实用工具包Scrapy安装教程

       对于想用每个想用Python开发网络爬虫的开发者来说,Scrapy无疑是一个极好的开源工具.今天安装之后觉得Scrapy的安装确实不易啊.所以在此博文一篇,往后来着少走弯路. 废话不多说了,如果 ...

  4. hdf第一周完了,突然时间静止.,醒了就早点去公司上班,再努力一点

    周一要了个任务,做评价完成,分享完成的页面,做到周四发现可能做不出来,找dzy,逻辑比较混乱,想要放弃了,感觉自己非常没用.昨天跟豆聊了一下,否定自己是一点意义也没有的,觉得自己很差劲,无助的感觉跟初 ...

  5. Java:按值传递还是按引用传递详细解说

    前天在做系统的时候被Java中参数传递问题卡了一下,回头查阅了相关的资料,对参数传递问题有了新的了解和掌握,但是有个问题感觉还是很模糊,就是Java中到底是否只存在值传递,因为在查阅资料时,经常看到有 ...

  6. QTextCodec::makeDecoder函数,plugins需要是动态链接库

    QT中的QString内容使用Unicode作为文本编码.但是实际系统中通常采用的是其他编码,例如GBK,utf8等.为了便于兼容这些格式,QT中还设置了两个字符串类型: QCString类: C类型 ...

  7. SQLAlchemy 一对多

    下述範例描述了電影同導演的多對一關係.範例中說明了從用戶定義的Python類建立數據表的方法,雙方關係例項的建立方法,以及最終查詢數據的方法:包括延遲載入和預先載入兩種自動生成的SQL查詢. 結構定義 ...

  8. proxy解析

    知其所以然 本文不是教程向,倾向于分析科学上网的一些原理.知其所以然,才能更好地使用工具,也可以创作出自己的工具. 科学上网的工具很多,八仙过海,各显神通,而且综合了各种技术.尝试从以下四个方面来解析 ...

  9. centos 安装 openerp

    遇到问题:近日公司提出openerp的搭建,觉得openerp里的有些模块比较适合公司,openerp的运作,估计会有利于公司系统化的管理.于是我就去了解openrp,然后来搭建这套强大的系统. 解决 ...

  10. Magento PDF发票,支持中文,以及修改的办法

    Magento PDF发票,支持中文,以及修改的办法.   如果让magento的PDF发票支持中文.Magento生成PDF发票.使用的是zend framework的zend_pdf类. 下面是一 ...