虚函数的使用 以及虚函数与重载的关系, 空虚函数的作用,纯虚函数->抽象类,基类虚析构函数使释放对象更彻底
为了访问公有派生类的特定成员,可以通过讲基类指针显示转换为派生类指针。
也可以将基类的非静态成员函数定义为虚函数(在函数前加上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虚析构函数是 ...
随机推荐
- linux的学习记录随笔
为什么学习linux 因为操作系统是一种介质,你要接触其中的东西,首先必须要有介质,而linux在服务器端是老大哥的地位,所以呢,学习linux吧. 学习的方式 可以看视频 imooc.百度传课.网易 ...
- HDU 1856 Brave Game(巴什博奕)
十年前读大学的时候,中国每年都要从国外引进一些电影大片,其中有一部电影就叫<勇敢者的游戏>(英文名称:Zathura),一直到现在,我依然对于电影中的部分电脑特技印象深刻. 今天,大家选择 ...
- Maven学习
http://www.cnblogs.com/sprinng/p/5141233.html 生成项目jar包失败 maven安装出现解决:http://blog.csdn.net/kjfcpua/ar ...
- python网络编程-TCP协议中的三次握手和四次挥手(图解)
建立TCP需要三次握手才能建立,而断开连接则需要四次握手.整个过程如下图所示: 先来看看如何建立连接的. 首先Client端发送连接请求报文,Server段接受连接后回复ACK报文,并为这次连接分配资 ...
- C#笔记
关键字: 1.internal 被 internal 修饰的东西只能在本程序集(当前项目)内被使用. 注意事项: 1.解决c#代码引用c/c++代码出现的unsafe code错误警告提示 Unsaf ...
- iOS事件传递->处理->响应
前言: 按照时间顺序,事件的生命周期是这样的: 事件的产生和传递(事件如何从父控件传递到子控件并寻找到最合适的view.寻找最合适的view的底层实现.拦截事件的处理)->找到最合适的view后 ...
- DBoW2库介绍
DBoW2库是University of Zaragoza里的Lopez等人开发的开源软件库. 由于在SLAM回环检测上的优异表现(特别是ORB-SLAM2),DBoW2库受到了广大SLAM爱好者的关 ...
- VirtualBox内ubuntu10.10系统和windows7 共享文件夹
材料 virtualbox 4.3.0 ubuntu10.10 window 7 sp1 步骤 1.安装好虚拟机和操作系统,(具体步骤网上有很多) 2.安装虚拟机的增强功能包, 安装完成手动系统重新, ...
- SVG中 transform矩阵遇到的兼容性问题
SVG transform矩阵遇到的兼容性问题.在chrome.safari.火狐.360极速浏览器上都正常显示的图,在手机端就不行啊!!! 先上图. 图1 PC端浏览器 图2 iPho ...
- Xamarin.ios 调用接口
NSString urlstring = new NSString("http://211.155.229.230:8585/api/users/postregister"); ...