虚函数的使用 以及虚函数与重载的关系, 空虚函数的作用,纯虚函数->抽象类,基类虚析构函数使释放对象更彻底
为了访问公有派生类的特定成员,可以通过讲基类指针显示转换为派生类指针。
也可以将基类的非静态成员函数定义为虚函数(在函数前加上virtual)
#include<iostream>
using namespace std; class base{
public:
/*virtual*/ void who(){ //define this function to virtual will be normal
cout << "this is the class of base !" << endl;
}
}; class derive1:public base{
public:
void who(){
cout << "this is the class of derive1 !" << endl;
}
};
class derive2 :public base{
public:
void who(){
cout << "this is the class of derive2 !" << endl;
}
};
int main(){
base beseObject, *p;
derive1 obj1;
derive2 obj2;
p = &beseObject;
p->who();
cout << "------------------------------" << endl;
p = &obj1;
p->who();
((derive1*)p)->who();
cout << "------------------------------" << endl;
p = &obj2;
p->who();
((derive2*)p)->who();
cout << "------------------------------" << endl;
obj1.who();
obj2.who();
int i;
cin >> i;
return ;
}
两次结果比较: 没加virtual:
;加virtual后:
与重载的关系:
#include<iostream>
using namespace std; class base{
public:
virtual void f1(){ //virtual function
cout << "f1 function of base " << endl;
}
virtual void f2(){ //virtual function
cout << "f2 function of base " << endl;
}
virtual void f3(){ //virtual function
cout << "f3 function of base " << endl;
}
void f4(){
cout << "f4 function of base " << endl;
}
}; class derive:public base{
public:
void f1(){ //virtual function
cout << "f1 function of derive " << endl;
}
virtual void f2(int x){ //lose virtual characteristic
cout << "f2 function of derive " << endl;
}
//f3(){ //wrong, not the same return type
// cout << "f3 function of base " << endl;
//}
void f4(){ //normal overload
cout << "f4 function of derive " << endl;
}
};
int main(){
base obj1, *ptr;
derive obj2;
ptr = &obj1;
ptr->f1();
ptr->f2();
ptr->f3();
ptr = &obj2;
ptr->f1();
ptr->f2();
ptr->f4();
int i;
cin >> i;
return ;
}
结果:

空虚函数在中间类里必须声明,以保证其后的派生类能使用该虚函数。建立一条从虚函数到派生类的虚函数路径。
#include<iostream>
using namespace std; class base{
public:
virtual void print(){
cout << "calss base!" << endl;
}
};
class son:public base{
public:
virtual void print(){ //empty virtual class
}
};
class grandson :public son{
public:
void print(){
cout << "calss grandson!" << endl;
}
};
void show(base* b){
b->print();
}
int main(){
base *pbase = new base;
son *pson = new son;
grandson *pgrandson = new grandson;
show(pbase);
show(pson);
show(pgrandson);
int i;
cin >> i;
return ;
}
结果:
存虚函数与抽象类
#include<iostream>
using namespace std; class shape{ //抽象类里必须有一个纯虚函数
public:
virtual float area() = ;
};
class triangle :public shape{
protected:
float h, w;
public:
triangle(float hh, float ww){
h = hh; w = ww;
}
float area(){
return h*w*0.5;
}
};
class rectangle :public shape{
protected:
float h, w;
public:
rectangle(float hh, float ww){
h = hh; w = ww;
}
float area(){
return h*w;
}
};
float total(shape* s[], int n){
float sum = ;
for (int i = ; i < n - ; i++)
sum += s[i]->area();
return sum;
}
int main(){
shape* s[];
s[] = new triangle(, );
s[] = new rectangle(, );
float sum = total(s, );
cout <<"total area is: "<< sum << endl;;
int i;
cin >> i;
return ;
}
结果:算出总面积 为 6
虚函数的使用 以及虚函数与重载的关系, 空虚函数的作用,纯虚函数->抽象类,基类虚析构函数使释放对象更彻底的更多相关文章
- 构造函数为什么不能为虚函数 & 基类的析构函数为什么要为虚函数
一.构造函数为什么不能为虚函数 1. 从存储空间角度,虚函数相应一个指向vtable虚函数表的指针,这大家都知道,但是这个指向vtable的指针事实上是存储在对象的内存空间的.问题出来了,假设构造函数 ...
- C++基类的析构函数定义为虚函数的原因
1:每个析构函数只会清理自己的成员(成员函数前没有virtual).2:可能是基类的指针指向派生类的对象,当析构一个指向派生类的成员的基类指针,这时程序不知道这么办,可能会造成内存的泄露,因此此时基类 ...
- C++ 由虚基类 虚继承 虚函数 到 虚函数表
//虚基类:一个类可以在一个类族中既被用作虚基类,也被用作非虚基类. class Base1{ public: Base1(){cout<<"Construct Base1!&q ...
- C++中基类的析构函数为什么要用virtual虚析构函数
知识背景 要弄明白这个问题,首先要了解下C++中的动态绑定. 关于动态绑定的讲解,请参阅: C++中的动态类型与动态绑定.虚函数.多态实现 正题 直接的讲,C++中基类采用virtual虚析构函数是 ...
- 读书笔记 effective c++ Item 7 在多态基类中将析构函数声明为虚析构函数
1. 继承体系中关于对象释放遇到的问题描述 1.1 手动释放 关于时间记录有很多种方法,因此为不同的计时方法创建一个TimeKeeper基类和一些派生类就再合理不过了: class TimeKeepe ...
- 基类的析构函数写成virtual虚析构函数
虚函数作用:动态绑定,实现多态效果. 场景问题: 派生类中有资源需要回收,而在编程中采用多态,由基类的指针指向派生类,则在释放的时候,如果基类的析构函数不是virtual,则派生类的析构函数得不到释放 ...
- C++中基类虚析构函数的作用及其原理分析
虚析构函数的理论前提是 执行完子类的析构函数,那么父类的虚构函数必然会被执行. 那么当用delete释放一个父类指针所实例化的子类对象时,如果没有定义虚析构函数,那么将只会调用父类的析构函数,而不会调 ...
- 【C++】C++中基类的析构函数为什么要用virtual虚析构函数?
正面回答: 当基类的析构函数不是虚函数,并且基类指针指向一个派生类对象,然后通过基类指针来删除这个派生类对象时,如果基类的析构函数不是虚析构函数,那么派生类的析构函数就不会被调用,从而产生内存泄漏 # ...
- C++-基类的析构函数为什么要加virtual虚析构函数(转)
知识背景 要弄明白这个问题,首先要了解下C++中的动态绑定. 关于动态绑定的讲解,请参阅: C++中的动态类型与动态绑定.虚函数.多态实现 正题 直接的讲,C++中基类采用virtual虚析构函数是 ...
随机推荐
- 教程三:Wechat库的使用
上一篇教程中我们提供了wechat的php的库,这里我们简要介绍一个这个库的源码和使用.这个库的主文件为`Wechat.php`,其余的几个文件都是为这个文件服务的,提供加解密,消息拼接等功能.`We ...
- Programming Contest Problem Types
Programming Contest Problem Types Hal Burch conducted an analysis over spring break of 1999 and ...
- python爬虫学习(11) —— 也写个AC自动机
0. 写在前面 本文记录了一个AC自动机的诞生! 之前看过有人用C++写过AC自动机,也有用C#写的,还有一个用nodejs写的.. C# 逆袭--自制日刷千题的AC自动机攻克HDU OJ HDU 自 ...
- vs2013 error : cannot open source file "SDKDDKVer.h"
改: 项目属性--常规--工具集--Visual Studio 2013-WindowsXP(v120_xp)
- Duplicate entry 'javajavajav' for key 'username'
org.apache.ibatis.exceptions.PersistenceException: ### Error updating database. Cause: com.mysql.jd ...
- [开源].NET数据库访问框架Chloe.ORM
扯淡 13年毕业之际,进入第一家公司实习,接触了 EntityFramework,当时就觉得这东西太牛了,访问数据库都可以做得这么轻松.优雅!毕竟那时还年轻,没见过世面.工作之前为了拿个实习机会混个工 ...
- [LeetCode] Binary Tree Upside Down 二叉树的上下颠倒
Given a binary tree where all the right nodes are either leaf nodes with a sibling (a left node that ...
- 20145215&20145307《信息安全系统设计基础》实验二 固件设计
20145215&20145307<信息安全系统设计基础>实验二 固件设计 实验目的与要求 了解多线程程序设计的基本原理,学习 pthread 库函数的使用. 了解在 linux ...
- Android中基于CGroup的memory子系统HAL层分析-lmkd
Android在内存管理上于Linux有些小的区别,其中一个就是引入了lowmemorykiller.从lowmemorykiller.c位于drivers/staging/android也可知道,属 ...
- Socket编程实践(3) 多连接服务器实现与简单P2P聊天程序例程
SO_REUSEADDR选项 在上一篇文章的最后我们贴出了一个简单的C/S通信的例程.在该例程序中,使用"Ctrl+c"结束通信后,服务器是无法立即重启的,如果尝试重启服务器,将被 ...