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

1 C++中,通过基类的引用(或指针)调用虚函数时,发生动态绑定,两个条件(基类引用或指针、虚函数)缺一不可

 虚函数的默认实参将发生静态绑定

2 继承层次的根类一般都需要定义虚析构函数

3 任意非static成员都可以是虚析构函数,static成员函数不能是虚析构函数(应为static成员不是属于某个对象的,而是属于整个类的)

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

 private成员:基类的private数据成员在派生类类型的对象中存在,但是派生类没有任何权限访问到基类的private成员

class A
{
private:
    int val;
};

class B:A
{
public:
    void func(){cout << val;}
};

 func将报错,因为val在派生类中是无权访问的

 是否可以理解为:基类中的private和protected成员在基类以外都是能通过基类类型对象来访问的,protected成员在派生类中是可见的,private成员在派生类中是不可见的

5 派生类中的虚函数和基类中的虚函数要保持一致,除非返回类型是基类类型的引用,则派生类中的虚函数返回的可以是及类类型或派生类类型的引用

6 基类类型的指针或引用调用虚函数时,可以通过作用域操作符实现覆盖虚函数动态绑定机制,即指定虚函数的版本

7 接口继承:public继承,即继承了基类的接口

 实现继承:protected继承和private继承,即从基类继承的部分并没有称为其接口的一部分,仅仅是便于其内部实现而已

 在实现继承中,可以通过在派生类的public声明下声明基类的成员,从而实现这些成员的public继承

8 static成员在整个继承层次中只有一个,如果是private类型,在派生类不能访问。static成员既可以使用作用域操作符来调用,又可以使用箭头操作符来调用

9 派生类中,构造函数总是先构造基类部分,再构造派生类部分,即使派生类构造函数初始化列表中没有基类构造函数,也将先调用基类的默认构造函数,构造基类部分

 派生类构造函数初始化列表中,只能初始化自己的直接基类(尊重基类接口)

10 派生类析构函数:派生类析构函数不负责撤销基类对象的成员,编译器总是显式调用派生类对象基类部分的析构函数,每个析构函数只负责清理自己的成员

  对象的撤销顺序与构造顺序相反,首先执行派生类析构函数,然后按继承层次依次向上调用各基类析构函数

11 虚析构函数:

  派生类自动调用基类析构函数撤销基类部分对基类的设计有重要的影响

  删除指向动态分配对象的指针时,在释放对象的内存之前,需要运行对象的析构函数。可是指针的静态类型可能与被删除对象的动态类型不同(可能会删除实际指向派生类对象的基类类型的指针),因此基类的析构函数要为虚析构函数,保证析构函数的动态绑定

12 纯虚函数:

  在虚函数形参表后面添上=0可以将虚函数定义为纯虚函数,含有(或继承)一个或多个纯虚函数的类称为抽象基类,抽象类不能创建对象

  如果一个类没有将从基类继承来的虚函数声明为纯虚函数,同时类没有实现自己的虚函数版本,则指向该类的指针动态调用虚函数时将使用继承类的虚函数版本,这可能不满足该类的用户调用该函数时的期望,所以将该函数声明为纯虚函数,这样将不能创建该类的对象

13 句柄类

  C++面向对象编程,却不能使用对象本身来支持面向对象编程,而必须使用指针或引用

  通用的技术是定义句柄类,句柄类存储和管理基类的指针,句柄的用户可以获得动态行为。

时间: 2025-01-13 07:07:18

c++primer复习(六)—面向对象编程的相关文章

《C++ Primer》之面向对象编程(中)

构造函数和复制控制 每个派生类对象由派生类中定义的(非 static)成员加上一个或多个基类子对象构成,当我们构造.复制.赋值和撤销一个派生类对象时,也会构造.复制.赋值和撤销这些基类子对象. 构造函数和复制控制成员不能继承,每个类定义自己的构造函数和复制控制成员.像任何类一样,如果类不定义自己的默认构造函数和复制控制成员,就将使用合成版本.//而不是靠继承 基类构造函数和复制控制 继承对基类构造函数的唯一影响是,在确定提供哪些构造函数时,必须考虑一类新用户.像任意其他成员一样,构造函数可以为

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

纯虚函数 在前面所提到过的 Disc_item 类提出了一个有趣的问题:该类从 Item_base 继承了 net_price 函数但没有重定义该函数.因为对 Disc_item 类而言没有可以给予该函数的意义,所以没有重定义该函数.在我们的应用程序中,Disc_item 不对应任何折扣策略,这个类的存在只是为了让其他类继承.//也就是说,Disc_item继承了Item_base中的虚函数net_price,但是由于Disc_item不需要net_price,所以它没有重定义net_price

《C++ Primer》之面向对象编程(三)

继承情况下的类作用域 在继承情况下,派生类的作用域嵌套在基类作用域中.如果不能在派生类作用域中确定名字,就在外围基类作用域中查找该名字的定义.正是这种类作用域的层次嵌套使我们能够直接访问基类的成员,就好象这些成员是派生类成员一样.如果编写如下代码: Bulk_item bulk; cout << bulk.book(); 名字 book 的使用将这样确定:bulk 是 Bulk_item 类对象,在 Bulk_item 类中查找,找不到名字 book:因为从 Item_base 派生 Bulk

python学习笔记(六) - 面向对象编程

一. 类和实例 aa 二. 访问限制 bb 三. 继承和多态 cc 四. 获取对象信息 dd

面向对象设计与面向对象编程

我发现,面向对象设计,被忽视的太严重了.使用OOP语言,却不是面向对象来设计.无非就是用类写C程序而已,而且这种情况还很常见.另一种情况是过度重视类,而忽视了对象,但是对象才是根本.不过本文会以类型为主,来介绍面向对象设计. 前言 面向对象是一个完全不同于传统软件设计方式的理念,传统软件设计是以功能为主体,以功能为模块,以功能为目标.而面向对象不同,是以软件运行中的组件为主体,实现某个功能,只是恰好这些组件的交互可以间接做到.这些组件,就是对象.用面向对象来设计软件,实际上就是设计一系列的对象,

C++ Primer 学习笔记_73_面向对象编程 --再谈文本查询示例

面向对象编程 --再谈文本查询示例 引言: 扩展第10.6节的文本查询应用程序,使我们的系统可以支持更复杂的查询. 为了说明问题,将用下面的简单小说来运行查询: Alice Emma has long flowing red hair. Her Daddy says when the wind blows through her hair, it looks almost alive, like a fiery bird in flight. A beautiful fiery bird, he

C++ Primer 学习笔记_74_面向对象编程 --再谈文本查询示例[续/习题]

面向对象编程 --再谈文本查询示例[续/习题] //P522 习题15.41 //1 in TextQuery.h #ifndef TEXTQUERY_H_INCLUDED #define TEXTQUERY_H_INCLUDED #include <iostream> #include <fstream> #include <sstream> #include <vector> #include <set> #include <map&g

C++ Primer 学习笔记_66_面向对象编程 --定义基类和派生类[续]

算法旨在用尽可能简单的思路解决问题,理解算法也应该是一个越看越简单的过程,当你看到算法里的一串概念,或者一大坨代码,第一感觉是复杂,此时不妨从例子入手,通过一个简单的例子,并编程实现,这个过程其实就可以理解清楚算法里的最重要的思想,之后扩展,对算法的引理或者更复杂的情况,对算法进行改进.最后,再考虑时间和空间复杂度的问题. 了解这个算法是源于在Network Alignment问题中,图论算法用得比较多,而对于alignment,特别是pairwise alignment, 又经常遇到maxim

C++ Primer 学习笔记_34_面向对象编程(5)--虚函数与多态(二):纯虚函数、抽象类、虚析构函数、动态创建对象

C++ Primer 学习笔记_34_面向对象编程(5)--虚函数与多态(二):纯虚函数.抽象类.虚析构函数.动态创建对象 一.纯虚函数 1.虚函数是实现多态性的前提 需要在基类中定义共同的接口 接口要定义为虚函数 2.如果基类的接口没办法实现怎么办? 如形状类Shape 解决方法 将这些接口定义为纯虚函数 3.在基类中不能给出有意义的虚函数定义,这时可以把它声明成纯虚函数,把它的定义留给派生类来做 4.定义纯虚函数: class <类名> { virtual <类型> <函