C++学习(一)-虚函数(1)
来源:互联网 发布:光盘盘面打印软件 编辑:程序博客网 时间:2024/05/21 06:18
1,多态性:是指不同对象收到相同的信息,产生不同的动作;简单地说,用一个名字定义不同的函数,这些函数执行不同但又类似的动作。也就是“一个接口,多钟方法”。
2,多态分为:编译时的多态和运行时的多态两种。
3,连编:是把函数名和函数体的程序代码连接在一起的过程。静态连编是在编译时完成的,动态连编是在运行时完成的,也就是在发生调用时,才去寻找和连接程序代码。
4,C++是编译性的,仍采用静态编译,但可以通过虚函数机制实现动态连编。编译时的多态性通过函数重载和运算符重载来实现。
5,(1)当基类指针指向子类对象时,基类指针调用基类和子类相同的函数时,调用的是基类的函数。
#include "stdafx.h"#include "iostream"using namespace std;class Base{ public: Base(int x,int y) { a=x; b=y; } void show() { cout<<"调用的是基类函数"<<endl; cout<<a<<" "<<b<<" "<<endl; } private: int a; int b;};class Derived:public Base{public:Derived(int x,int y,int z):Base(x,y){c=z;} void show()//和基类相同的函数{ cout<<"调用的是子类函数"<<endl; cout<<"c="<<c<<endl;}private:int c;};int main(){Derived *pc=new Derived(30,50,40); Base mc (30,20),*pb;pb=pc; //基类指针指向子类对象//pc->show(); pb->show(); //基类指针调用基类和子类相同的函数时,调用的是基类的函数return 0; }
实验结果如下:
(2) 当基类的函数被设置为虚函数时,调用的子类中的函数。
#include "stdafx.h"#include "iostream"using namespace std;class Base{ public: Base(int x,int y) { a=x; b=y; } virtual void show()//设置为虚函数 { cout<<"调用的是基类函数"<<endl; cout<<a<<" "<<b<<" "<<endl; } private: int a; int b;};class Derived:public Base{public:Derived(int x,int y,int z):Base(x,y){c=z;} void show(){ cout<<"调用的是子类函数"<<endl; cout<<"c="<<c<<endl;}private:int c;};int main(){Derived *pc=new Derived(30,50,40); Base mc (30,20),*pb;pb=pc; //基类指针指向子类对象//pc->show(); pb->show(); //基类指针调用基类和子类相同的函数时,调用的是子类的函数return 0; }
实验结果如下:
(3) 当基类的虚函数带有缺省参数时时,调用的是基类中函数,即缺省参数的虚函数是静态绑定的。
#include "stdafx.h"#include "iostream"using namespace std;class Base{ public: Base(int x,int y) { a=x; b=y; } virtual void show(char* value="我是缺省参数")//基类虚函数为缺省参数 { cout<<"调用的是基类函数"<<endl; cout<<a<<" "<<b<<" "<<value<<"\n"<<endl; } private: int a; int b;};class Derived:public Base{public:Derived(int x,int y,int z):Base(x,y){c=z;} void show(){ cout<<"调用的是子类函数"<<endl; cout<<"c="<<c<<endl;}private:int c;};int main(){Derived *pc=new Derived(30,50,40); Base mc (30,20),*pb;pb=pc; //基类指针指向子类对象//pc->show(); pb->show(); //基类指针调用基类和子类相同的函数时,调用的是基类的函数return 0; }
实验结果如下:
以上(1),(2),(3),全都是基类对象指针指向子类对象。
(4),当子类对象指针调用基类和子类相同的函数时,调用的是子类中的函数。
#include "stdafx.h"#include "iostream"using namespace std;class Base{ public: Base(int x,int y) { a=x; b=y; } void show()//和子类相同的函数 { cout<<"调用的是基类函数"<<endl; cout<<a<<" "<<b<<"\n"<<endl; } private: int a; int b;};class Derived:public Base{public:Derived(int x,int y,int z):Base(x,y){c=z;} void show()//和基类相同的函数{ cout<<"调用的是子类函数"<<endl; cout<<"c="<<c<<endl;}private:int c;};int main(){Derived *pc=new Derived(30,50,40); Base mc (30,20),*pb;//pb=pc; //基类指针指向子类对象pc->show(); //子类对象指针调用基类和子类相同的函数时,调用的时子类的函数。//pb->show(); return 0; }
实验结果如下:
(5) 子类可以继承基类的函数,并且在一定继承方式下,可以访问它,也就是说,子类没有基类同名的函数,在一定方式下,可以访问基类函数
#include "stdafx.h"#include "iostream"using namespace std;class Base{ public: Base(int x,int y) { a=x; b=y; } void show() { cout<<"调用的是基类函数"<<endl; cout<<a<<" "<<b<<"\n"<<endl; } private: int a; int b;};class Derived:public Base{public:Derived(int x,int y,int z):Base(x,y){c=z;}private:int c;};int main(){Derived *pc=new Derived(30,50,40); //子类对象指针Base mc (30,20),*pb;//pb=pc; //基类指针指向子类对象pc->show(); //子类对象指针调用基类函数//pb->show(); return 0; }
实验结果如下:
(6),子类对象指针可以指向基类对象,但是必须强制类型转换。此时即使子类对象指针指向基类对象,在调用基类和子类相同函数时,调用的是子类函数。
#include "stdafx.h"#include "iostream"using namespace std;class Base{ public: Base(int x,int y) { a=x; b=y; } void show() { cout<<"调用的是基类函数"<<endl; cout<<a<<" "<<b<<"\n"<<endl; } private: int a; int b;};class Derived:public Base{public:Derived(int x,int y,int z):Base(x,y){c=z;}void show(){cout<<"调用的是子类函数"<<endl;//cout<<c<<"\n"<<endl;}private:int c;};int main(){Derived *pc=new Derived(30,50,40); //子类对象指针Base mc (30,20),*pb;pc=(Derived*)&mc; //子类对象指针指向基类对象pc->show(); //子类对象指针调用子类函数//pb->show(); return 0; }
实验结果:
(7),当子类指针指向基类对象时,必须强制类型转换,若基类和子类中有相同的函数,并且该函数为虚函数,用子类对象指针访问该函数时,访问的是基类中的函数。
#include "stdafx.h"#include "iostream"using namespace std;class Base{ public: Base(int x,int y) { a=x; b=y; } virtual void show()//设置为虚函数 { cout<<"调用的是基类函数"<<endl; cout<<a<<" "<<b<<"\n"<<endl; } private: int a; int b;};class Derived:public Base{public:Derived(int x,int y,int z):Base(x,y){c=z;}void show(){cout<<"调用的是子类函数"<<endl;//cout<<c<<"\n"<<endl;}private:int c;};int main(){Derived *pc=new Derived(30,50,40); //子类对象指针Base mc (30,20),*pb;pc=(Derived*)&mc; //子类对象指针指向基类对象pc->show(); //子类对象指针调用基类函数//pb->show(); return 0; }
实验结果如下:
总结:对于基类和子类中具有的相同函数,对象指针访问函数的选择,依据于其所属的类型,当该函数为虚函数;对象指针访问函数选择,依据于其指向的对象。
7,使用对象指针的目的是为了表达一种动态的性质,即当指针指向不同对象时,执行不同的操作。
8,虚函数的定义是在基类中进行的,当某个函数被定义为虚函数,其在一个或多个派生类中可以被重新定义,但是,其函数原型,包括返回值类型,函数名,形参个数,形参类型及顺序,必须与基类中原型完全相同。这也是与重载函数一个不同的地方。
9,通过定义虚函数机制来实现多态时,派生类必须从它的基类中公有继承。
10,只有通过基类指针访问虚函数,才能获得运行时的多态性。
11,一个虚函数无论被公有继承多少次,都保有虚函数的特性。
12,虚函数必须是其所在类的成员函数,不能是友元函数,也不能是静态成员函数,因为虚函数调用必须依靠指定的对象来决定该激活哪一个函数。
13,内联函数不能是虚函数,因为内联函数不能再运行时确定其位置。
14,构造函数不能是虚函数,但是析构函数可以是虚函数,并且通常是虚函数。
- c 语言学习之printf函数(一)
- [C学习]函数(?)
- C语言函数(一)
- [C++]函数对象(一)
- 函数重载 C++(一)
- C++学习(一)-虚函数(1)
- 字符串函数学习(一)
- MySql函数学习(一)
- Makefile函数学习(一)
- python学习(一)-函数
- C++test 学习(一)
- C语言学习(一)
- c 学习笔记 (一)
- c#winform学习(一)
- C基础学习(一)
- C语言学习(一)
- C语言学习(一)
- C学习笔记(一)
- vsftp上传文件出现553 Could not create file解决方法
- Flatten Binary Tree to Linked List
- encodeURI(),encodeURIComponent()和escape()
- iOS关于block的内存管理
- 一个95后国外小伙子眼中的社交网络,7大国外社交平台观点
- C++学习(一)-虚函数(1)
- Web前后分离架构研发模式de演变
- libgdx 1.7.0版本发布,支持IOS 9
- 通过蓝牙调试(穿戴设备app) - 开发文档翻译
- ASP.NET实现QQ、微信、新浪微博OAuth2.0授权登录
- 爱上Linux(1)-Linux命令初解
- codeforces 540 D. Bad Luck Island (概率dp)
- 成为核心程序员的一些建议
- SQL优化