题外话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++ 继承、函数重载的更多相关文章

  1. C++ 函数重载与函数匹配

    <C++ Primer>笔记,整理关于函数重载与函数匹配的笔记. 函数重载 void func(int a); //原函数 void func(double a); //正确:形参类型不同 ...

  2. php继承与重载

    <?php class A { public $param = "paramA"; public function test() { echo "testA&quo ...

  3. php 之 类,对象(三)多态性,函数重载,克隆

    一.三大特性之三 多态性(在php中表象不明显)1.概念:当父类引用指向子类实例时,由于子类对父类函数进行了重写,导致我们在使用该引用去调用相应的方法显示出的不同.2.发生条件:1.必须有继承 2. ...

  4. 5.3 C++用顶层函数重载操作符

    参考:http://www.weixueyuan.net/view/6381.html 总结: 可以将操作符重载函数声明为顶层函数. 如果以顶层函数的形式重载操作符时,二元操作符重载函数必须有两个参数 ...

  5. python中函数重载和重写

    python 中的重载  在python中,具有重载的思想却没有重载的概念.所以有的人说python这么语言并不支持函数重载,有的人说python具有重载功能.实际上python编程中具有重载的目的缺 ...

  6. 函数重载(overload)和函数重写(override)

    1. 前言: 在C++中有两个非常容易混淆的概念,分别是函数重载(overload)和函数重写(overwirte).虽然只相差一个字,但是它们两者之间的差别还是非常巨大的. 而通过深入了解这两个概念 ...

  7. 0607pm克隆&引用类&加载类&面向对象串讲&函数重载

    克隆class Ren{ public $name; public $sex; function __construct($n,$s) { $this->name=$n; $this->s ...

  8. C++学习_继承覆盖重载

    今天通过对实验二继承,重载,覆盖的学习,让我更深一步理解了这些概念的区别. 首先来明确一个概念,函数名即地址,也就是说函数名就是个指针. 编译阶段,编译器为每个函数的代码分配一个地址空间并编译函数代码 ...

  9. 深入浅出TypeScript(3)- 函数重载和泛型

    面向对象特性中,最根本的就是面向对象的三大基本特征:封装.继承.多态.同时,TypeScript中也存在多态的使用,比如函数重载,今天我们先看一下函数重载以及泛型的概念. 什么是函数重载 简单来说,函 ...

随机推荐

  1. GO1.6语言学习笔记3-工具篇(SublimeText 3+GoSublime组合)

    选择SublimeText作为开发工具的原因,最最主要的是它够轻巧,搭配GO开发才能有飞一般的感觉.当然作为开发工具之一,Sublime组合工具也提供足够强大的功能. 自动化提示代码 保存的时候自动格 ...

  2. .Net程序猿玩转Android开发---(11)页面跳转

    在不论什么程序开发中,都会遇到页面之间跳转的情况,Android开发也不例外.这一节,我们来认识下Android项目中如何进行页面跳转.页面跳转分为有參数和无參数页面跳转,已经接受还有一个页面的返回值 ...

  3. python 下载.whl 文件,查看已安装软件包方法

    下载地址       https://www.lfd.uci.edu/~gohlke/pythonlibs/ 另一个Python packages地址为    https://pypi.org/ 下载 ...

  4. 解决svchost占用内存过高问题

    摘抄自:https://jingyan.baidu.com/article/d169e1867cea7e436611d801.html svchost占用内存过高,会导致内存100%电脑卡住,CPU温 ...

  5. mysql工作中常见问题

    1.Error Code: 1044 - Access denied for user 'root'@'localhost' to database 'information_schema'Query ...

  6. Redis 实现队列优先级

    通常使用一个list来实现队列操作,这样有一个小限制,所以的任务统一都是先进先出,如果想优先处理某个任务就不太好处理了,这就需要让队列有优先级的概念,我们就可以优先处理高级别的任务. 实现方式: (1 ...

  7. 关于WCF服务的调试跟踪

    关于WCF服务的调试跟踪信息,请利用好以下几个工具,具体的例子MSDN上都有,进去看吧... 服务跟踪查看器工具 (SvcTraceViewer.exe): http://msdn.microsoft ...

  8. SQL SERVER树形结构数据——批量删除分组数据

    定义函数获取某结点下所有子结点: CREATE FUNCTION [dbo].[fn_GetSubGroupInfoById] ( @id AS INT --某分组Id ) RETURNS @SubG ...

  9. vim利用插件管理工具-管理配置文件

    目前被广泛应用的2各插件管理工具Pathogen和Vunble,我先说Pathogen Pathogen Pathogen完全用vim脚本编写,不用其他的代码(Vunble就用了python),所以安 ...

  10. [docker]docker0网络模型探究

    docker0网络模型step by step 将docker的ns软链到linux ns $ ln -s /var/run/docker/netns /var/run/netns 查看ns,无 $ ...