There is a base class at the root of the hierarchy, from which the other class inherit, directly or indirectly.

These inheriting classes are known as derived calsses.

The key ideas in Object-Oriented Programming are data abstraction, inheritance and dynamic binding.

Using data abstraction, we only expose the interface and hide the detail implementation.

Through inheritance, we define classes that model relationships among similar types.

Through dynamic binding, we can use the objects of these types and ignore the detail how they differ.

Dynamic binding

In C++, dynamic binding happens when a virtual function is called through a reference(or pointer) to a base class.

class Quote{
public:
virtual double net_price(size_t n) const;
} class Bulk_quote : public Quote{
public:
double net_price(size_t n) const;
} void print_total(ostream & os, const Quote & item, size_t n){
os << item.net_price(n);
} print_total(cout, base, ); // base has Quote type, call Ouote version
print_total(cout, bulk, ); // bulk has Bulk_quote, call bulk_quote version

The decision as to which version to run depends on the type of argument at run time. Therefore, dynamic binding is known as runtime binding.

Basic class ordinarily should define a virtual destructor. Virtual destructor are needed even if they do not work.

Any non-static member function, other than constructor, maybe virtual. The virtual keyword only appear on the declaration inside the class, and may not appear on the definition that apper outside the class body.

A function that is virtual in base class is implicitly virtual in the derived classess as well.

Member functions that are not declared as virtual are resolved at compile time, not run time.

If a derived class do not override the virtual from its base, then like any other member, the derived class inherit the version defined in the base class.

A derived class contains subobject corresponding to its base class. We can an object of a derived class as if it was an object of its base class. We can bind an reference(or pointer) to the base-class part of a derived class.

    Quotes item;        // an object of base type
Bulk_quote bulk;   // an object of derived type
Quotes *p = &item; // p points to a Quote object
p = &bulk;      // p points the Quote part of bulck
Quote & ref = bulk; // ref bound to the Quote part of bulck

The fact that the derived object contains subobjects for its base classes is the key to how inheritance work.

Like any ohter code that create an objec to the base-class type, a derived class must use a base-class constructor to initialize its base-class part.

Bulk_quote(const string& bookNo, double price, size_t qty, double disc): Quote(bookNo, price), min_qty(qty), discount(dis) {}

Process flow:

  1. The Quote constructor initializes the base-class part of the Bulk_quote. E.g. the bookNO and price members
  2. execute the empty Quote constructor body
  3. Initilize the direct member min_qty and discount
  4. execute the empty function body of Bulk_quote constructor

The keyword final prevent a class from being used as a base class

    class NoDerived final { /*  */};
class DerivedType : NoDerived { /* */}; // error NoDerived is final

The static type is the type of a variable or other expression. The static type of an express is always known at compile time - it is the type with which a variable is declared or an expression yields.

The dynamic type is the type of an object. The dynamic type is the type of object in momery that the variable or expression represents. The dynamic type may not know until run time.

There is a implicit(automatic) conversion from base to derived. A base object may not contain members defined by the derived class.

    Quote base;
Bulk_quote * bulk = &base; // error: cannot convert base to derived
Bulk_quote & bulkRef = base; // error: cannot convert base to derived

If we know the conversion is safe, we can use static_cast to make the conversion.

When we initialize an object of base type from an object of derived type, only the base part of the derived object is copied, moved or assigned. The derived part of the derived object is ignored.

Reference:

C++ Primer, Fifth Edition, chapter 15 Object-Oriented Programming

[C++] OOP - Base and Derived Classes的更多相关文章

  1. How can I protect derived classes from breaking when I change the internal parts of the base class?

    How can I protect derived classes from breaking when I change the internal parts of the base class? ...

  2. 【转载】#330 - Derived Classes Do Not Inherit Constructors

    A derived class inherits all of the members of a base class except for its constructors. You must de ...

  3. Virtual functions in derived classes

    In C++, once a member function is declared as a virtual function in a base class, it becomes virtual ...

  4. [C++] OOP - Virtual Functions and Abstract Base Classes

    Ordinarily, if we do not use a function, we do not need to supply a definition of the function. Howe ...

  5. C++ Core Guidelines

    C++ Core Guidelines September 9, 2015 Editors: Bjarne Stroustrup Herb Sutter This document is a very ...

  6. C++ Knowledge series 1

    Programming language evolves always along with Compiler's evolvement. 1. The C++ Object Model: Strou ...

  7. <Effective C++>读书摘要--Inheritance and Object-Oriented Design<一>

    1.Furthermore, I explain what the different features in C++ really mean — what you are really expres ...

  8. Swift 中的静态方法继承

    Base and Derived Classes: class BaseClass{ class func staticMethod(){ println("BaseClass.static ...

  9. 【足迹C++primer】52、,转换和继承虚函数

    转换和继承,虚函数 Understanding conversions between base and derived classes is essential to understanding h ...

随机推荐

  1. Ubuntu下Zabbix结合percona监控mysql数据

    按道理来说zabbix就自带的MySQL插件来监控mysql数据库,但是你会发现,自带的mysql监控项是很少的,根本满足不了公司的需求.由于它本身自带的模板太过简单了,所以需要做更详细的监控,而pe ...

  2. vue服务端渲染缓存应用

    vue缓存分为页面缓存.组建缓存.接口缓存,这里我主要说到了页面缓存和组建缓存 页面缓存: 在server.js中设置 const LRU = require('lru-cache') const m ...

  3. mt7620a拓展串口

    mt7620a拓展串口 要修改的文件有两个: mt7620a.dtsi 进入/home/ihid/chaos_calmer/target/linux/ramips/dts/mt7620a.dtsi p ...

  4. QWT编译与配置-Windows/Linux环境

    QWT编译与配置-Windows/Linux环境 QWT和FFTW两种开源组件是常用的工程软件支持组件,QWT可以提供丰富的绘图组件功能,FFTW是优秀数字波形分析软件.本文使用基于LGPL版权协议的 ...

  5. Flask基本介绍

    Fask 1.Flask简介 Flask是一个基于Python开发并且依赖jinja2模板和Werkzeug WSGI服务的一个微型框架对于Werkzeug本质是socket服务端,其用于接收http ...

  6. 找球号(三)南阳acm528(异或' ^ ')

    找球号(三) 时间限制:2000 ms  |  内存限制:10000 KB 难度:2   描述 xiaod现在正在某个球场负责网球的管理工作.为了方便管理,他把每个球都编了号,且每个编号的球的总个数都 ...

  7. swig与python

    当你觉得python慢的时候,当你的c/c++代码难以用在python上的时候,你可能会注意这篇文章.swig是一个可以把c/c++代码封装为python库的工具.(本文封装为python3的库) 文 ...

  8. 一个java新手配置IIS服务器的血泪史

    接到一个二次开发项目,听说是asp页面,带着不要怂的态度于是接下了. 好嘛按照步骤来 1.了解需求:一个公司内部积分排名类型项目,已经被多次开发,我所需要的就是新增两个页面,一个是分店赛一个是分部赛. ...

  9. SQL Server 中对 FOR XML和FROM的转换处理

    在SQL Server中对XML的再操作转换: 方法1: --生成XML SELECT * FROM [T_BAS_预算科目] FOR XML PATH --把XML转成SQL表 declare @X ...

  10. Java设计模式(23)——行为模式之访问者模式(Visitor)

    一.概述 概念 作用于某个对象群中各个对象的操作.它可以使你在不改变这些对象本身的情况下,定义作用于这些对象的新操作. 引入 试想这样一个场景,在一个Collection中放入了一大堆的各种对象的引用 ...