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中也存在多态的使用,比如函数重载,今天我们先看一下函数重载以及泛型的概念. 什么是函数重载 简单来说,函 ...
随机推荐
- background-image:url(data:image/gif;base64,XXXX) base64方式将本地图片添加到文档中
background-image:url(data:image/gif;base64,R0lGODlhCwAMAMZjAElxvlNvtVRxtkp1v0p9wVh7vkqBwl58vml6vml7v ...
- MAR 27 解决华为手机访问Google Play:从服务器检索信息时出错。[DF-DFERH-01]
虽然路由器已经设置了梯子,但是用华为手机访问Google Play时,还是提示:从服务器检索信息时出错.[DF-DFERH-01]. 虽然在手机上把梯子设置成全局模式,连接Google Play后 ...
- php json的相关操作
类与json <?php class userinfo { var $user_name; var $user_ip; var $user_logintime; } $u = new useri ...
- Spring Cloud构建微服务架构(四)分布式配置中心(续)
先来回顾一下,在前文中我们完成了什么: 构建了config-server,连接到Git仓库 在Git上创建了一个config-repo目录,用来存储配置信息 构建了config-client,来获取G ...
- [na]锐起无盘机并发部署多台windows
小时候很好奇这个技术,也并无卵,只是为了遂儿时愿, 用到锐起无盘部署,支持win7哦: 视频教程: 拓展:网吧电脑为什么没有硬盘? 网吧电脑没有硬盘是怎么运行的? 所需软件: https://yunp ...
- google protocol buffer的原理和使用(三)
介绍下怎么反序列化GoogleBuffer数据.并在最后提供本系列文章中所用到的代码整理供下载. 上一篇文章介绍了如何将数据序列化到了addressbook.data中.那么对于接受方而言该怎么解析出 ...
- 普通用户su 到root,无需密码方式,及iptables封掉本机某个端口,core文件配置
一. 普通用户su到root无需密码: 随着服务器越来越多,普通用户转到root下,去查密码表是个很繁琐的事,发现有如下方式比较方便(需要root操作) vi /etc/pam.d/su 将 aut ...
- 每日英语:Some Chinese Students Stay Home to Get Ahead
Li Shan's oldest son was the perfect candidate to join the throngs of Chinese students studying abro ...
- 新手福利:Apache Spark入门攻略
[编者按]时至今日,Spark已成为大数据领域最火的一个开源项目,具备高性能.易于使用等特性.然而作为一个年轻的开源项目,其使用上存在的挑战亦不可为不大,这里为大家分享SciSpike软件架构师Ash ...
- Sql Server连接字符串
SQL Server .NET Data Provider 连接字符串包含一个由一些属性名/值对组成的集合.每一个属性/值对都由分号隔开. PropertyName1=Value1; ...