1.除了构造函数之外,任意非static成员函数都可以是虚函数。保留字virtual只在类内部的成员函数声明处出现,不能用在类定义体外部出现的函数定义上。

2.派生类只能通过派生类对象访问其基类的protected成员,派生类对其基类类型对象的protected成员没有特殊访问权限。

3.派生类中虚函数的声明必须与基类中的定义方式完全匹配,但有一个例外:返回对基类的引用(或指针)的虚函数。派生类中的虚函数可以返回基类函数所返回类型的派生类的引用(或指针)。

4.因为每个派生类对象都有基类部分,类可以访问其基类的public和protected成员,就好像那些成员是派生类自己的成员一样。

5.要触发动态绑定,必须满足两个条件:
(1)只有指定为虚函数的成员函数才能进行动态绑定

(2)必须通过基类类型的引用或指针进行函数调用。

6.引用和指针的静态类型与动态类型可以不同,这是C++用以支持多态性的基石。

如果调用非虚函数,则无论实际对象是什么类型,都执行基类类型所定义的函数。如果调用虚函数,则直到运行时才能确定调用哪个函数,运行的虚函数是引用所绑定的或指针所指向的对象所属类型定义的版本。

7.如果虚函数有默认实参,通过基类的引用或指针调用虚函数时,默认实参为基类虚函数声明中指定的值,但是调用的是派生类的虚函数。

8.使用class保留字定义的派生类默认具有private继承,而用struct保留字定义类默认具有public继承。

classBase{ /*.....*/ };
structD1:Base{ /*.....*/}; //publicinheritanceby default classD2:Base{ /*.....*/}; //privateinheritance by default

9.友元关系不能继承。基类的友元对派生类的成员没有特殊访问权限。如果基类被授予友元关系,则只有基类具有特殊访问权限,该基类的派生类不能访问授予友元关系。

classBase
{
friend class Frnd;
protected:
int i;
}; classD1:public Base
{
protected:
int j;
}; classFrnd
{
public:
int mem(Base b) { returnb.i; } //OK:Frnd is friend to Base
int mem(D1 d) { return d.i;} //error:friendship doesn'tinherit
}; classD2:public Frnd
{
int mem(Base b) { return b.i;}//error:friendship doesn't inherit
};

10.如果基类定义了static成员,则整个继承层次中只有一个这样的成员。无论从基类派生出多少个派生类,每个static成员只有一个实例。

static成员遵循常规访问控制:如果成员在基类中为private,则派生类不能访问它。假定可以访问成员,则既可以通过基类访问static成员,也可以通过派生类访问static成员。

11.派生类合成的默认构造函数与非派生的构造函数只有一点不同:除了初始化派生类的数据成员之外,它还初始化派生类对象的基类部分。基类部分由基类的默认构造函数初始化。(初始化顺序:先调用基类的默认构造函数,再初始化派生类的成员。

12.只包含类类型或内置数据类型数据成员、不含指针的类一般可以使用合成操作,复制、赋值或撤销这样的成员函数不需要特殊控制。具有指针成员的类一般需要定义自己的复制控制来管理这些成员。

13.如果派生类显式定义自己的复制构造函数或赋值构造操作符,则该定义将完全覆盖默认定义。派生类的复制构造函数和赋值操作符负责对基类成分以及类自己的成员进行复制或赋值。

如果派生类定义了自己的复制构造函数,该复制构造函数一般应显式使用基类复制构造函数初始化对象的基类部分:

classBase { /*.....*/ };
classDerived: public Base
{
public:
Derived(const Derived& d):
Base(d) /*other memberinitialization*/
{ /*....*/ }
};

初始化函数Base(d)将派生类对象d转换为它的基类部分的引用,并调用基类复制构造函数。如果省略基类初始化函数,如下代码:

Derived(constDerived& d) /*derived member initializations*/
{/*....*/ }

效果是运行Base的默认构造函数初始化对象的基类部分。假定Derived成员的初始化从d复制对应成员,则新构造的对象将具有奇怪的配置:它的Base部分讲保存默认值,而它的Derived成员是另一个对象的副本。

14.赋值操作符通常与复制构造函数类似:如果派生类定义了自己的赋值操作符,则该操作符必须对基类部分进行显式赋值。

Derived&Derived::operator=(constDerived &rhs)
{
if ( this != &rhs )
Base::operator=(rhs);
return *this;
}

15.如果派生类中的拷贝和赋值构造函数中没有“显式指定基类的拷贝和赋值构造函数”,即派生类只是把自己的成员进行了赋值,基类部分是调用基类的默认构造函数。

16.对象、引用或指针的静态类型决定了对象能够完成的行为。甚至当静态类型和动态类型可能不同的时候,就像使用基类类型的引用或指针时可能会发生的,静态类型仍然决定着可以使用什么成员。

17.在基类和派生类中使用同一个名字的成员函数,其行为与数据成员一样:在派生类作用域中派生类成员将屏蔽基类成员。即使函数原型不同,基类成员也会被屏蔽。

18.确定函数调用遵循以下四个步骤(注意顺序):

(1)首先确定进行函数调用的对象、引用或指针的静态类型。

(2)在该类中查找函数,(只要函数名相同就行,函数原型不管)如果找不到,就在直接基类中查找,如此遵循着类的继承链往上找,直到找到该函数或者查找完最后一个类。如果不能在类或其相关基类中找到该名字,则调用时错误的。

(3)一旦找到了该名字,就进行常规类型检查,查看如果给定找到的定义,该函数调用是否合法。

(4)假定函数调用合法,编译器就生成代码。如果函数是虚函数且通过引用或指针调用,则编译器生成代码以确定根据对象的动态类型运行哪个函数版本,否则,编译器生成代码直接调用函数。

19.将函数定义为纯虚函数能够说明,该函数为后代类型提供了可以覆盖的接口,但是这个类中的版本决不会调用。试图创建抽象基类的对象将发生编译时错误。

含有(或继承)一个或多个纯虚函数的类似抽象基类。除了作为抽象基类的派生类的对象的组成部分,不能创建抽象类型的对象。

C++ Primer 有感(面向对象编程)的更多相关文章

  1. C++ Primer 学习笔记_67_面向对象编程 --转换与继承、复制控制与继承

    面向对象编程 --转换与继承.复制控制与继承 I.转换与继承 引言: 由于每一个派生类对象都包括一个基类部分,因此能够像使用基类对象一样在派生类对象上执行操作. 对于指针/引用,能够将派生类对象的指针 ...

  2. c++primer复习(六)—面向对象编程

    1 C++中,通过基类的引用(或指针)调用虚函数时,发生动态绑定,两个条件(基类引用或指针.虚函数)缺一不可 虚函数的默认实参将发生静态绑定 2 继承层次的根类一般都需要定义虚析构函数 3 任意非st ...

  3. C++ Primer 学习笔记_69_面向对象编程 --继承情况下的类作用域

    面向对象编程 --继承情况下的类作用域 引言: 在继承情况下,派生类的作用域嵌套在基类作用域中:假设不能在派生类作用域中确定名字,就在外围基类作用域中查找该名字的定义. 正是这样的类作用域的层次嵌套使 ...

  4. 《C++ Primer》之面向对象编程(四)

    纯虚函数 在前面所提到过的 Disc_item 类提出了一个有趣的问题:该类从 Item_base 继承了 net_price 函数但没有重定义该函数.因为对 Disc_item 类而言没有可以给予该 ...

  5. 《C++ Primer》之面向对象编程(一)

    面向对象编程基于三个基本概念:数据抽象.继承和动态绑定.//动态绑定使编译器能够在运行时决定是使用基类中定义的函数还是派生类中定义的函数. 面向对象编程的关键思想是多态性(polymorphism). ...

  6. <C++Primer>第四版 阅读笔记 第四部分 “面向对象编程与泛型编程”

    继承和动态绑定与数据抽象一起成为面向对象编程的基础. 模板使我们能够编写独立于具体类型的泛型类和泛型函数. 第15章 面向对象编程 面向对象编程基于三个基本概念:数据抽象.继承和动态绑定.在C++中, ...

  7. C++ Primer 学习笔记_72_面向对象编程 --句柄类与继承[续]

    面向对象编程 --句柄类与继承[续] 三.句柄的使用 使用Sales_item对象能够更easy地编写书店应用程序.代码将不必管理Item_base对象的指针,但仍然能够获得通过Sales_item对 ...

  8. C++ Primer(第4版)-学习笔记-第4部分:面向对象编程与泛型编程

    第15章 面向对象编程OOP(Object-oriented programming)           面向对象编程基于三个基本概念:数据抽象.继承和动态绑定.      在 C++ 中,用类进行 ...

  9. C++ 面向对象编程

    <C++ Primer 4th>读书笔记 面向对象编程基于三个基本概念:数据抽象.继承和动态绑定.在 C++ 中,用类进行数据抽象,用类派生从一个类继承另一个:派生类继承基类的成员.动态绑 ...

  10. 泛型编程、STL的概念、STL模板思想及其六大组件的关系,以及泛型编程(GP)、STL、面向对象编程(OOP)、C++之间的关系

    2013-08-11 10:46:39 介绍STL模板的书,有两本比较经典: 一本是<Generic Programming and the STL>,中文翻译为<泛型编程与STL& ...

随机推荐

  1. font-spider利器对webfont网页字体压缩使用

    http://font-spider.org/ npm install font-spider -g hyheilizhitij(汉仪黑荔枝体简) //引入 @font-face{ font-fami ...

  2. 89. Gray Code(中等,了解啥是 gray code)

    知道啥是 gray code 就是收获了. 下面介绍了 gray code 发明的 motivation, 了解动机后就知道啥是 gray code 了. https://zh.wikipedia.o ...

  3. Luogu P2756 [网络流24题]飞行员配对方案问题_二分图匹配

    二分图模板题 我用的是匈牙利 其实最大流也可以做 #include<iostream> #include<cstdio> #include<cstdlib> #in ...

  4. 在循环列表的富文本里摘出每个item的img标签内容(适合vue渲染)

    昨天在做公司项目的社区动态内容.后台接口返回的数据是数组套对象,对象里有富文本,然后需要摘出富文本里的img标签在列表里分开渲染(即图片九宫格样式).最终效果如图: 这个是后盾接口返回的json数据 ...

  5. URL重定向漏洞,python打造URL重定向漏洞检测脚本

    前言: 今天学习了重定向漏洞,这个漏洞比较好理解 漏洞名:URL重定向漏洞 威胁:低 漏洞的来源:开发者对head头做好对应的过滤和限制 例子: 有漏洞的网站:http://a.com/x.php?u ...

  6. PHP date() 函数

    实例 格式化本地日期和时间,并返回格式化的日期字符串: <?php // Prints the dayecho date("l") . "<br>&qu ...

  7. PHP 实例 AJAX 与 XML

    在 PHP 中,AJAX 可用来与 XML 文件进行交互式通信,具体的通信过程,请参考本文内容! AJAX XML 实例 下面的实例将演示网页如何通过 AJAX 从 XML 文件读取信息: 实例   ...

  8. Docker内核能力机制

    能力机制(Capability)是 Linux 内核一个强大的特性,可以提供细粒度的权限访问控制. Linux 内核自 2.2 版本起就支持能力机制,它将权限划分为更加细粒度的操作能力,既可以作用在进 ...

  9. 安卓高级6 CoordinatorLayout

    原作者大神地址:http://blog.csdn.net/huachao1001/article/details/51554608 曾在网上找了一些关于CoordinatorLayout的教程,大部分 ...

  10. 《Java多线程编程核心技术》推荐

    写这篇博客主要是给猿友们推荐一本书<Java多线程编程核心技术>. 之所以要推荐它,主要因为这本书写得十分通俗易懂,以实例贯穿整本书,使得原本抽象的概念,理解起来不再抽象. 只要你有一点点 ...