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. JavaScript常用DOM操作方法和函数

    查找节点ocument.querySelector(selectors) //接受一个CSS选择器作为参数,返回第一个匹配该选择器的元素节点.document.querySelectorAll(sel ...

  2. springboot-redis缓存

    Redis缓存使用 1.  引入依赖(可能已经引入了):spring-boot-starter-cache 2.  在application.yml配置文件中配置spring:redis:host/p ...

  3. thinkphp5配置讲解

    一.thinkphp配置类型有哪些? 1.在thinkphp中,有6种配置.即惯例配置,应用配置.扩展配置.模块配置.场景配置.动态配置. 2.惯例配置就是系统默认的配置. 3.应用配置就是我们自己开 ...

  4. 基于C语言的面向对象编程

    嵌入式软件开发中,虽然很多的开发工具已经支持C++的开发,但是因为有时考虑运行效率和编程习惯,还是有很多人喜欢用C来开发嵌入式软件.Miro Samek说:"我在开发现场发现,很多嵌入式软件 ...

  5. B/S与C/S架构简介

    概念: C/S结构,即Client/Server(客户机/服务器)结构,是大家熟知的软件系统体系结构,通过将任务合理分配到Client端和Server端,降低了系统的通讯开销,可以充分利用两端硬件环境 ...

  6. linux运维视频教程

    视频教程:https://www.bilibili.com/video/av31023006/?p=2 1.文件系统 文件系统树形结构: 对于linux系统的user和application来说,并不 ...

  7. rails应用页面导出为pdf文档

    1.下载安装wkhtmltox https://wkhtmltopdf.org/downloads.html   2.gemfile添加 gem 'pdfkit' #页面导出pdf gem 'wkht ...

  8. 【数据结构】循环链表&&双向链表详解和代码实例

    喜欢的话可以扫码关注我们的公众号哦,更多精彩尽在微信公众号[程序猿声] 01 循环链表 1.1 什么是循环链表? 前面介绍了单链表,相信大家还记得相关的概念.其实循环链表跟单链表也没有差别很多,只是在 ...

  9. Java面向对象之抽象方法&接口

    在开始写抽象类之前,有一个问题我觉得想清楚会对理解抽象类很有帮助:那就是为什么要设计抽象类? 难道用类还不够么,为什么要设计出抽象类这样一个东西.我们可以换个角度来理解,就是有些类本来就是不应该被实例 ...

  10. inner join(inner可省) 与 left join 之间的区别

    关于inner join 与 left join 之间的区别,以前以为自己搞懂了,今天从前端取参数的时候发现不是预想中的结果,才知道问题出在inner join 上了. 需求是从数据库查数据,在前端以 ...