C++ 继承、函数重载
题外话1:浪费了两天,可耻!
题外话2:你这个年纪,做得好是理所当然,做不好是罪孽深重!!! --- 深以为然。
题外话3:从开始看C++ Primer 到现在,整整24天了,没想到基础方面耗费这么久---主要是没想到C++居然如此繁琐。精勤求学,当持之以恒。
面向对象的三大特征:数据抽象、继承、动态绑定。其实就是Java中说的封装、继承、多态,翻译的不同而已。
多态这个词用的不好,太抽象,动态绑定就清晰的多。
继承语法
class B : public A { /*类B*/ };
上面最重要的就是“:”和public。前者记住就行,继承的语法规定。后者是权限访问符(我更喜欢叫它继承权限),public、protected、private。
继承权限和父类成员的访问权限,共同决定了继承的成员在子类中的访问权限---继承权限可以进一步限制,但不能放松---最小访问控制。
例如父类的public成员a,继承权限为private,则a在子类中就是private部分。
这里只有一个需要注意的点,如果省略继承权限,那么 class 默认为private,struct默认为public。
补充:
//using声明导入
class Derived : private Base {
public:
// maintain access levels for members related to the size of the object
using Base::size;
protected:
using Base::n;
// ...
};
继承的结构
子类对象的父类部分其实就是一个父类对象!这个认识很重要!
父类的引用或者指针,指向的就是子类对象的父类对象部分!!!
动态绑定
首先,这是一个运行期的概念,它出现的条件是:通过父类的引用或指针调用函数。
这点同Java的概念一样。但有一点不同:动态绑定仅限于 virtual 函数!
就是说,普通的函数不会动态绑定!!!这个认识更重要!
普通函数的绑定是编译器进行的,静态绑定。
这里的关键点是,父类的引用或者指针是静态类型,而子类对象(或者父类本身的对象)是在运行期才知道的。所以叫动态绑定。
就是说,对象的实际类型可能不同于父类的引用或指针类型,这是C++动态绑定的关键。
关于虚函数
不是重载,是重写。
如果想调用某个父类的虚函数,需要使用作用域操作符,如 A::x(); --仅限于子类的成员函数中调用。
注意:虚函数的默认实参如果不一致,会导致问题。
继承之初始化
隐式的,会调用父类的默认构造进行初始化。再初始化子类自身的成员。
显式的,只能在子类的初始化列表中调用父类的构造进行初始化。
--- 注意,都是先初始化父类对象,且只能直接初始化直接父类。
继承之复制控制
隐式的,会调用父类的复制控制操作父类成员。再调用子类的复制控制。
如果自定义了复制构造函数,应该显式的调用父类的复制构造函数操作父类成员。
如果自定义了赋值操作符,应该显式的调用父类的赋值操作符操作父类成员。
--- 注意,必须防止赋值操作符操作自身!
B &B::operator=(const B &rhs){
if(this != &rhs){
A::operator=(rhs); // 显式调用父类的赋值操作符
/*其他*/
}
}
继承之析构函数
注意,子类析构不负责父类析构,而是由编译器显式的调用父类的析构函数!
需要将根类的析构函数设为虚函数!!
析构顺序与构造顺序相反。
纯虚函数
在虚函数的参数列表后面加上 =0 ,即将该虚函数声明为纯虚函数。
具有该函数的类将无法创建对象。
--这个就和Java的抽象方法、抽象类一致了。
重要
在构造或者析构期间,总是先构造父类或者析构子类,这时类型是不完整的。
为了解决这个问题,编译器将构造或者析构期间的对象看作父类对象!!!
所以,构造或者析构期间调用的虚函数只会是构造或者析构函数所在类的虚函数!不是子类的虚函数!!!
函数重载
子类的同名函数会覆盖掉父类中所有的同名函数--哪怕是不同的函数原型!!!(务必注意,非 virtual)
认真的说,我不认为这是重载,不过书上这么叫,那就这么叫吧。
这种覆盖用起来很不爽,因为完全覆盖了所有的父类版本。所幸我们有比较好的解决办法:使用using声明。
#include <iostream> using namespace std; // 根类的析构函数,必须virtual。
// 子类的函数会覆盖父类的同名函数。
// 如果想重载,使用using声明即可。
class A
{
public:
A(){};
virtual ~A(){};
void hi(){
cout<<"hi from A"<<endl;
}
void hi(string name){
cout<<"hi "<<name<<" from A"<<endl;
}
}; class B:public A
{
public:
B(){};
~B(){};
using A::hi; // using 声明
void hi(int num){
cout<<"hi num["<<num<<"] from B, overloaded"<<endl;
} }; int main(int argc, char const *argv[])
{
B b;
b.hi();
b.hi("joe");
b.hi(); return ;
}
继承特性:
友元关系不能继承。
静态成员只会存在一个实例。
构造函数和复制控制不能继承。
根类的析构函数应该设为虚函数。
构造函数和析构函数都只能调用所在类的函数,哪怕是虚函数---就是说构造或者析构期间没有动态绑定。
C++ 继承、函数重载的更多相关文章
- C++ 函数重载与函数匹配
<C++ Primer>笔记,整理关于函数重载与函数匹配的笔记. 函数重载 void func(int a); //原函数 void func(double a); //正确:形参类型不同 ...
- php继承与重载
<?php class A { public $param = "paramA"; public function test() { echo "testA&quo ...
- php 之 类,对象(三)多态性,函数重载,克隆
一.三大特性之三 多态性(在php中表象不明显)1.概念:当父类引用指向子类实例时,由于子类对父类函数进行了重写,导致我们在使用该引用去调用相应的方法显示出的不同.2.发生条件:1.必须有继承 2. ...
- 5.3 C++用顶层函数重载操作符
参考:http://www.weixueyuan.net/view/6381.html 总结: 可以将操作符重载函数声明为顶层函数. 如果以顶层函数的形式重载操作符时,二元操作符重载函数必须有两个参数 ...
- python中函数重载和重写
python 中的重载 在python中,具有重载的思想却没有重载的概念.所以有的人说python这么语言并不支持函数重载,有的人说python具有重载功能.实际上python编程中具有重载的目的缺 ...
- 函数重载(overload)和函数重写(override)
1. 前言: 在C++中有两个非常容易混淆的概念,分别是函数重载(overload)和函数重写(overwirte).虽然只相差一个字,但是它们两者之间的差别还是非常巨大的. 而通过深入了解这两个概念 ...
- 0607pm克隆&引用类&加载类&面向对象串讲&函数重载
克隆class Ren{ public $name; public $sex; function __construct($n,$s) { $this->name=$n; $this->s ...
- C++学习_继承覆盖重载
今天通过对实验二继承,重载,覆盖的学习,让我更深一步理解了这些概念的区别. 首先来明确一个概念,函数名即地址,也就是说函数名就是个指针. 编译阶段,编译器为每个函数的代码分配一个地址空间并编译函数代码 ...
- 深入浅出TypeScript(3)- 函数重载和泛型
面向对象特性中,最根本的就是面向对象的三大基本特征:封装.继承.多态.同时,TypeScript中也存在多态的使用,比如函数重载,今天我们先看一下函数重载以及泛型的概念. 什么是函数重载 简单来说,函 ...
随机推荐
- 云从科技 OCR任务 pixel-anchor 方法
云从科技提出了一种端到端的深度学习文本检测框架Pixel-Anchor,通过特征共享的方式高效的把像素级别的图像语义分割和锚检测回归放入一个网络之中, 把像素分割结果转换为锚检测回归过程中的一种注意力 ...
- shell case语法
在阅读hadoop相关的脚本文件时,遇到case语句,好久不写shell,忘了不少,复习下shell的case语句: 运行结果: ...
- 请教中文的OCR软件哪个最好?
对原件,有这几种:1,全中文(含标点,一些英文符号)2,中英文(英文较多,或英文占大多数)3,全英文(这个用finereader8.0) 針對1.2 紫光 超星阅读器自带的OCR组件 尚书七号搞定全中 ...
- 如何在 Visual Studio 2013 中调试.NET Framework 4.5.1 代码
版本需求如标题,在 工具->选项->调试->常规 中,更改以下设置: 禁用:启用“仅我的代码”.逐过程执行属性和运算符(仅限托管).要求源文件与原始版本完全匹配 启用:启用 .NET ...
- OpenWrt加入iptables 支持过滤字符串
须要在iptables命令选项中选择mod filter Network->Firewall->iptables->mod filter Kernel Modules->Net ...
- vim:去掉响铃
vim在移动字符出界(上下左右)包括按<ESC>建都会响铃,有时候真的很烦. 在网上搜了一下,原来是visualbell来控制的,在vim里使用命令:help visualbell,原来禁 ...
- Android UI视图效果篇之仿QQ好友列表分组悬浮PinnedHeaderExpandableListView
楼主是在平板上測试的.图片略微有点大,大家看看效果就好 接下来贴源代码: PinnedHeaderExpandableListView.java 要注意的是 在 onGroupClick方法中pare ...
- C++顺序容器vector、deque、list
1.容器元素类型 C++中大多数数据类型能够作为容器的元素类型.容器元素类型必须满足一下两个条件:支持赋值和复制操作. 所以没有元素是引用类型的容器,同一时候IO对象和auto_ptr也不能作为容器的 ...
- electron-vue 项目搭建的地址
https://simulatedgreg.gitbooks.io/electron-vue/content/en/ 现在的网址:vue的electron的文件: https://github.com ...
- VC++ 获取本地IP和计算机名
主要是两个函数的使用,gethostname();.gethostbyname(); 自定义两个函数GetLocalHostName获取计算机名.GetIPAddress获取IP地址 int CIPD ...