C++primer读书笔记11-多态
多态也是C++中的一个重要的方面。多态和动态类型,虚函数本质上是指同样的事情。
1 虚函数
类中的成员函数原型前面加上virtual 表面这个函数是个虚函数。虚函数的目的是为了在继承它的派生类中又一次定义这个函数,以便于通过基类的指针或引用在执行时对派生类的函数进行调用。
2 派生类和虚函数
派生类普通情况下要重定义所继承的虚函数。有几个注意事项。
<1>虚函数的声明必须和基类中的函数声明原型全然一致。例外的是当基类返回基类型的指针或者引用的时候。派生类能够派生类类型的指针或者引用
<2>virtual 关键词加不加无所谓,可是一般要加上,能看的清楚这是个虚函数
<3>virtual的标签一旦在基类中的函数前面加上。就永远也去不掉
3 动态绑定的触发
C++的函数调用默认不使用动态绑定。使用动态绑定须要两个必须的条件
<1>通过基类类型的指针或者引用进行函数的调用
<2>函数是虚函数
通过这里也能够说明,当通过指针或者引用调用函数的时候,即便派生类重定义了基类的版本号。也不会调用派生类的版本号。由于它不会触发多态。
4 虚函数的覆盖机制
有时候通过指针或者引用不想触发多态。此时能够通过加限定符来显式的调用基类的函数
Derived d;
Base *p = &d;
p->Base::func();
假设在派生类中的函数定义的时候想要调用基类的同名函数那么也要这样显式的调用,否则会引发无穷递归。
5 虚函数跟复制控制
<1>通常将析构函数设置为虚函数,这是由于析构函数在运行的时候仅仅会运行自身的部分。
比如通过基类的指针或者引用来调用析构函数的话,那么仅仅会调用基类的构造函数。派生类的构造函数将不会被调用。
<2>构造函数不能定义为虚函数,由于在构造函数是在对象全然构造之前执行的。在构造函数执行的时候,对象的动态类型还不完整。
<3>赋值操作符原理上能够设置为虚函数。可是这样做是没意义的。原因例如以下:
虚函数要求函数原型全然一致,这当中包含了函数參数类型的一致,假设我们把operator = 设置为虚函数。那么在基类中函数的參数是基类类型,在派生类虚函数的參数类型依旧是基类类型。可是赋值操作符是要求函数參数类型和类类型一致。这样就会产生很easy混淆的东西。
class Base{
public:
virtual Base& operator =(Base& xx);
} class Derived : public Base
{
public:
virtual Derived& operator =(Base& xx); //virtual function
Derived& operator =(Derived& xx); //real operator =
}
6 构造函数和析构函数中的虚函数
在执行构造函数和析构函数的时候。此时的对象都不是一个完整的类。这个时候编译器将对象的对象视作在构造期间发生了变化,假设在当中调用虚函数的话。那么调用的将会是类自身类型
定义的版本号。
原因:基类在构造的时候,派生类部分的成员还没有初始化,假设此时调用的是派生类的虚函数,那么派生类的虚函数訪问类成员就会出问题。
同理基类的析构函数也是这样子。由于析构函
数直管自身成员的释放,派生类在调用析构函数的时候先调用自身的析构函数。然后再去调用基类的析构函数。所以基类的析构函数不可能调用派生类的虚函数,由于派生类的成员已经被释
放。实比例如以下:
//Base.h
#pragma once
#include <iostream>
using namespace std; class Base
{
public:
Base(void){ func();};
~Base(void){ funp();};
virtual void func(){cout<<"this is in Base constructor"<<endl;}
virtual void funp(){cout<<"this is in Base destructor"<<endl;};
};
//Derived.h
#pragma once
#include "base.h"
class Derived :
public Base
{
public:
Derived(void){func();}
~Derived(void){func();}
virtual void func(){cout<<"this is in Derived constructor"<<endl;}
virtual void funp(){cout<<"this is in Derived destructor"<<endl;};
};
//main.cpp
#include "Derived.h" void main()
{
Base X;
Derived Y;
}
7 纯虚函数
虚函数的形參后面跟上“=0”则表示纯虚函数。纯虚函数须要注意的有下面几点:
<1>纯虚函数没有函数体;
<2>最后面的“=0”并不表示函数返回值为0,它仅仅起形式上的作用。告诉编译系统“这是纯虚函数”;
<3>这是一个声明语句,最后应有分号。
<4>函数不能被调用
<5>不能创建有纯虚函数的类对象
<6>假设在一个类中声明了纯虚函数,而在其派生类中没有对该函数定义。则该虚函数在派生类中仍然为纯虚函数。
含有一个或者多个纯虚函数的类被称为抽象类。抽象类不能创建对象。抽象类的意义在于提供功能基础接口。然后由派生类来实现,在此基础上实现多态。可是抽象类能够作为引用或者指针。
实例程序例如以下:
//Base.h
#pragma once
#include <iostream>
using namespace std; class Base
{
public:
Base(void){ func();};
~Base(void){ funp();};
virtual void func(){cout<<"this is in Base constructor"<<endl;}
virtual void funp(){cout<<"this is in Base destructor"<<endl;};
virtual void fuck()=0;
};
//Derived.h
#pragma once
#include "base.h"
class Derived :
public Base
{
public:
Derived(void){func();}
~Derived(void){func();}
virtual void func(){cout<<"this is in Derived constructor"<<endl;}
virtual void funp(){cout<<"this is in Derived destructor"<<endl;};
virtual void fuck(){cout<<"what a fuck day it is!"<<endl;}
};
//main.cpp
#include "Derived.h" void main()
{
Derived Y;
Base& X = Y;
}
C++primer读书笔记11-多态的更多相关文章
- 机器学习实战 - 读书笔记(11) - 使用Apriori算法进行关联分析
前言 最近在看Peter Harrington写的"机器学习实战",这是我的学习心得,这次是第11章 - 使用Apriori算法进行关联分析. 基本概念 关联分析(associat ...
- 强化学习读书笔记 - 11 - off-policy的近似方法
强化学习读书笔记 - 11 - off-policy的近似方法 学习笔记: Reinforcement Learning: An Introduction, Richard S. Sutton and ...
- Key Technologies Primer 读书笔记,翻译 --- Struct 学习 1
原文链接:https://struts.apache.org/primer.html 本来想写成读书笔记的,结果还是变成翻译,谨作记录,学习. 1.HTML -- 见我前面文章 2.Interne ...
- 《精通Spring 4.X企业应用开发实战》读书笔记1-1(IoC容器和Bean)
很长一段时间关注在Java Web开发的方向上,提及到Jave Web开发就绕不开Spring全家桶系列,使用面向百度,谷歌的编程方法能够完成大部分的工作.但是这种不系统的了解总觉得自己的知识有所欠缺 ...
- c++ primer 读书笔记
顺序容器:为程序提供控制元素存储和访问顺序的能力,这种顺序与元素加入到容器时的位置相对应,而与元素值无关. 另外还有根据关键字的值来存储元素的容器:有序.无序关联容器. 另外STL还有三种容器适配器, ...
- c++ primer读书笔记之c++11(四)
1 带有作用域的枚举 scoped-enumeration 相信大家都用过枚举量,都是不带有作用域的,在头文件中定义需要特别注意不要出现重名的情况.为了解决这种问题,c++11提供了带作用于的枚举. ...
- c++ primer读书笔记之c++11(三)
1 =default构造函数限定符 c++11针对构造函数提供了=default限定符,可以用于显式指定编译器自动生成特定的构造函数.析构或赋值运算函数.参考代码如下: class CtorDftTy ...
- c++ primer读书笔记之c++11(二)
1 新的STL模板类型,std::initializer_list<T> c++11添加了initializer_list模板类型,用于提供参数是同类型情况的可变长度的参数传递机制,头文件 ...
- c++ primer读书笔记之c++11(一)
1 新的关键词nullptr c++11引入新的关键词nullptr,用于表示空指针,用于替换之前c提供的NULL(最初NULL是定义在stdlib中的宏定义,通常是0). 2 新的别名定义机制 al ...
- C++ Primer 读书笔记:第11章 泛型算法
第11章 泛型算法 1.概述 泛型算法依赖于迭代器,而不是依赖容器,需要指定作用的区间,即[开始,结束),表示的区间,如上所示 此外还需要元素是可比的,如果元素本身是不可比的,那么可以自己定义比较函数 ...
随机推荐
- NYIST 860 又见01背包
又见01背包时间限制:1000 ms | 内存限制:65535 KB难度:3 描述 有n个重量和价值分别为wi 和 vi 的 物品,从这些物品中选择总重量不超过 W 的物品,求所有挑选方案中物品价值总 ...
- (转)Linux内核 TCP/IP、Socket参数调优
Doc1: /proc/sys/net目录 所有的TCP/IP参数都位于/proc/sys/net目录下(请注意,对/proc/sys/net目录下内容的修改都是临时的,任何修改在系统重启后都会丢失) ...
- HDU 4333 Contest 4
一开始就想到了扩展KMP,因为只有扩展KMP才是处理后缀的.但忽然短路以为扩展KMP求的是最长公共后缀,囧....又浪费了很多时间,都是对这个算法练得不多 再看那个扩展KMP算法之后,就很确定要的就是 ...
- 程序猿的量化交易之路(21)--Cointrader之Currency货币实体(9)
转载须注明出自:http://blog.csdn.net/minimicall? viewmode=contents,http://cloudtrader.top 货币,Cointrader中基本实体 ...
- 纯粹的K12精髓 - 名师指导整理《20以内加法口诀表》
纯粹的K12精髓 - 名师指导整理<20以内加法口诀表> 太阳火神的漂亮人生 (http://blog.csdn.net/opengl_es) 本文遵循"署名-非商业用途-保持一 ...
- hdu5240
想了辣么多 貌似就一个条件 #include<bits/stdc++.h> using namespace std; int flag=0;int main(){int t,n,kase= ...
- iOS 从各种效果图颜色标注生成 UIColor
iOS 从各种效果图颜色标注生成 UIColor 太阳火神的漂亮人生 (http://blog.csdn.net/opengl_es) 本文遵循"署名-非商业用途-保持一致"创作公 ...
- python解压,压缩,以及存数据库的相关操作
zipfile实现压缩整个目录和子目录 import os,shutil,zipfile,glob def dfs_get_zip_file(input_path,result): # files = ...
- Oracle GoldenGate
Oracle GoldenGate实现数据库同步 前言:最近刚好在弄数据库同步,网上查了些资料再加上自己整理了一些,做个分享! 一.GoldenGate的安装 官方文档: Oracle®GoldenG ...
- Activity-数据状态的保存
由于手机是便捷式移动设备,掌握在用户的手中,它的展示方向我们是无法预知的,具有不确定性.平时我们拿着手机多数为竖屏,但有时候我们感觉累了也会躺着去使用手机,那么这时手机屏幕的展示方向可能已经被用户切换 ...