[C++] OOP - Base and Derived Classes
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:
- The Quote constructor initializes the base-class part of the Bulk_quote. E.g. the bookNO and price members
- execute the empty Quote constructor body
- Initilize the direct member min_qty and discount
- 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的更多相关文章
- 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? ...
- 【转载】#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 ...
- Virtual functions in derived classes
In C++, once a member function is declared as a virtual function in a base class, it becomes virtual ...
- [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 ...
- C++ Core Guidelines
C++ Core Guidelines September 9, 2015 Editors: Bjarne Stroustrup Herb Sutter This document is a very ...
- C++ Knowledge series 1
Programming language evolves always along with Compiler's evolvement. 1. The C++ Object Model: Strou ...
- <Effective C++>读书摘要--Inheritance and Object-Oriented Design<一>
1.Furthermore, I explain what the different features in C++ really mean — what you are really expres ...
- Swift 中的静态方法继承
Base and Derived Classes: class BaseClass{ class func staticMethod(){ println("BaseClass.static ...
- 【足迹C++primer】52、,转换和继承虚函数
转换和继承,虚函数 Understanding conversions between base and derived classes is essential to understanding h ...
随机推荐
- 个人免签即时到账收款接口 bufpay.com 支持多账号收款
有很多 bufpay 的用户反馈,单个手机收款有些时候不太方便,切换手机太麻烦:或者是营业额比较多,希望分摊到多个账号上面. 基于以上的问题,bufpay 开发了多手机收款的功能:每个收款的手机安装 ...
- mysql学习记录,CASE WHEN THEN ELSE END用法
记mysql,case when then else end用法 用法1:搜索函数 SELECT r.order_no, r.golds, r.pay_tool, , ) ) END AS price ...
- 【读书笔记 - Effective Java】01. 考虑用静态工厂方法代替构造器
获取类的实例有两种方法: 1. 提供一个公有的构造器(最常用). 2. 提供一个公有的静态工厂方法(static factory method). // 静态工厂方法示例 public static ...
- IOS移动端(H5)alert/confirm提示信息去除url
前几天写移动端项目用alert和confirm进行信息提示,但发现在iOS系统中,每次提示信息上面都会被添加一行URL地址,安卓却没有,经过查找之后,果然不出所料,兼容!!兼容!!!兼容!!! 需要重 ...
- Spark运行模式_Spark自带Cluster Manager的Standalone Client模式(集群)
终于说到了体现分布式计算价值的地方了! 和单机运行的模式不同,这里必须在执行应用程序前,先启动Spark的Master和Worker守护进程.不用启动Hadoop服务,除非你用到了HDFS的内容. 启 ...
- Linux字符设备驱动--No.3
字符驱动(按键)初始化函数分析: int charDrvInit(void) { devNum = MKDEV(reg_major, reg_minor); printk(KERN_EMERG&quo ...
- UART学习之路(四)VerilogHDL实现的简单UART,VIVADO下完成仿真
用VerilogHDL实现UART并完成仿真就算是对UART整个技术有了全面的理解,同时也算是Verilog入门了.整个UART分为3部分完成,发送模块(Transmitter),接收模块(Recei ...
- AMD,CMD,CommonJs,UMD讲解
一.CommonJS CommonJS规范加载模块是同步的,只有加载完成,才能执行后面的操作 CommonJS规范中的module.exports和require 每个文件就是一个模块,有自己的作用域 ...
- C/S与B/S 区别以及优缺点
1.什么是C/S结构 C/S (Client/Server)结构,即客户机和服务器结构.它是软件系统体系结构,通过它可以充分利用两端硬件环境的优势,将任务合理分配到Client端和Server端来实现 ...
- BZOJ3293_分金币_KEY
题目传送门 设x[i]表示i+1向i传的糖果数,x[n]表示1向n传的糖果数,a'=(a[1]+...a[N])/N a[1]+x[1]−x[n]=a' a[2]+x[2]−x[1]=a' a[3]+ ...