C++ 视频课笔记7
来源:互联网 发布:js手机端touch事件 编辑:程序博客网 时间:2024/06/01 22:59
在父类Shape,和子类Circle,子类Rect的虚构函数前加 virtual 变为virtual ~Shape();virtual ~Circle();virtual ~Rect(); 则问题就得以解决
5.3虚函数和虚析构函数原理
虚函数
指针指向函数地址——函数指针,一个指针占4个内存大小。
函数的覆盖和隐藏(可能面试题)
如上图,在子类当中没有定义同名的虚函数时,函数指针的入口地址就是和父类相同的,如果在子类当中定义了同名的虚函数,则子类的同名函数的入口地址就会变成子函数自己的,和父类不同,也就是会覆盖父类的函数指针的值
虚析构函数
理论前提:执行完子类的析构函数就会执行父类的析构函数
5.4纯虚函数抽象类
virtual double calcPerimeter() = 0;没有结构体,后面要加 = 0的虚函数叫纯虚函数。
包含纯虚函数的类叫做 抽象类 , 抽象类无法实例化对象,因为在虚函数列表中,纯虚函数直接地址是0,无法调用。抽象类的子类也可以是抽象类。
5.5接口类
仅含有纯虚函数的类称为接口类(类中无数据成员,也无构造和析构函数,只有成员函数,且成员函数都是纯虚函数)
接口类更多的是表达一种能力或协议
5.6运行时类型识别(RTTI)
typeid——dynamic_cast
dynamic_cast注意事项:
1.只能应用于指针和引用的转换
2.要转换的类型中必须包含虚函数
3.转换成功返回子类的地址,失败返回NULL
typeid注意事项
1.type_id返回一个type_info对象的引用
2.如果想通过基类的指针获得派生类的数据类型,基类必须带有虚函数
3.只能获取对象的实际类型
#include<iostream>
#include<stdlib.h>
#include<string>
#include"Plane.h"
#include"Bird.h"
using namespace std;
/* RTTI
1.Flyable类,成员函数:take off、land
2.Plane类,成员函数:take off、land、carry
3.Bird类,成员函数:take off、land、foraging
4.全局函数doSomething(Flyable *obj) */
void doSomething(Flyable *obj)
{
cout << typeid(*obj).name() << endl; //可返回变量的类型名称
obj->takeoff();
if (typeid(*obj) == typeid(Bird))
{
Bird *bird = dynamic_cast<Bird *>(obj);
bird->foraging();
}
if (typeid(*obj) == typeid(Plane))
{
Plane *plane = dynamic_cast<Plane *>(obj);
plane->carry();
}
obj->land();
}
int main()
{
Flyable *p = new Bird();
cout << typeid(p).name() << endl;
cout << typeid(*p).name() << endl;
Bird b;
Plane a;
doSomething(&b);
doSomething(&a);
system("pause");
return 0;
}
#ifndef FLYABLE_H
#define FLYABLE_H
#include<iostream>
class Flyable
{
public:
virtual void takeoff() = 0;
virtual void land() = 0;
};
#endif
#ifndef PLANE_H
#define PLANE_H
#include<iostream>
#include"Flyable.h"
class Plane: public Flyable
{
public:
virtual void takeoff();
virtual void land();
virtual void carry();
};
#endif
#include"Plane.h"
using namespace std;
void Plane::takeoff()
{
cout << "Plane--takeoff" << endl;
}
void Plane::land()
{
cout << "Plane--land" << endl;
}
void Plane::carry()
{
cout << "Plane--carry" << endl;
}
#ifndef BIRD_H
#define BIRD_H
#include<iostream>
#include"Flyable.h"
class Bird:public Flyable
{
public:
virtual void takeoff();
virtual void land();
virtual void foraging();
};
#endif
#ifndef BIRD_H
#define BIRD_H
#include<iostream>
#include"Flyable.h"
class Bird:public Flyable
{
public:
virtual void takeoff();
virtual void land();
virtual void foraging();
};
#endif
5.7异常处理
对有可能发生异常的地方做出预见性的安排
关键字:try...catch (尝试...捕获...) throw(抛出异常)
基本思想:主逻辑与异常处理分离
常见异常:
1.数组下标越界
2.除数为0
3.内存不足(越来越少见)
#include<iostream>
#include<stdlib.h>
#include<string>
#include"IndexException.h"
using namespace std;
void test()
{
throw IndexException();
}
int main()
{
try
{
test();
}
catch (IndexException &a)
{
a.printException();
}
system("pause");
return 0;
}
#ifndef EXCEPTION_H
#define EXCEPTION_H
#include<iostream>
class Exception
{
public:
virtual void printException();
virtual ~Exception(){}
};
#endif
#include"Exception.h"
#include<iostream>
using namespace std;
void Exception::printException()
{
cout << "Exception--printException()" << endl;
}
#ifndef INDEXEXCEPTION_H
#define INDEXEXCEPTION_H
#include<iostream>
#include"Exception.h"
class IndexException:public Exception
{
public:
virtual void printException();
};
#endif
#include"IndexException.h"
#include<iostream>
using namespace std;
void IndexException::printException()
{
cout << "提示:下标越界。" << endl;
}
阅读全文
0 0
- C++ 视频课笔记7
- C语言视频学习笔记
- 看朱老师视频笔记-------C语言
- C++ 视频课笔记1
- C++ 视频课笔记2
- C++ 视频课笔记3
- C++ 视频课笔记4
- C++ 视频课笔记5
- C++ 视频课笔记6
- C++ 视频课笔记8
- 视频学习第一课笔记
- object c内存管理总结(关东升老师视频笔记)
- opencv(C++)视频流读入-学习笔记3
- 视频笔记
- 视频 笔记
- 视频笔记
- OpenCV笔记7:视频播放控制
- (笔记)韩顺平linux(视频7-8.08)学习笔记
- Python学习心得(五) random生成验证码、MD5加密、pickle与json的序列化和反序列化
- C++ 视频课笔记6
- python中的类属性和实例属性
- hdu 1028 Ignatius and the Princess III(生成函数)
- 学习笔记3
- C++ 视频课笔记7
- ThinkPHP中实现微信支付(jsapi支付)流程
- Laravel 基础
- liunx必知必会(1)
- 杭电2567寻梦(字符串处理)
- Algorithm 2
- 垃圾收集器-GC以及判断对象存活的算法以及引用类型
- PHP实现微信申请退款
- 数据库出现ORA-00283/ORA-01610的问题