虚函数继承和虚继承是完全不同的两个概念。
虚函数继承是解决多态性的,当用基类指针指向派生类对象的时候,基类指针调用虚函数的时候会自动调用派生类的虚函数,这就是多态性,也叫动态编联。
虚继承就是为了节约内存,他是多重继承中的特有的概念。适用于菱形继承形式。
#include<iostream> using namespace std; class Shape //抽象类,不能创建对象 { protected: int m_a; int m_b; public: virtual double GetS()=0;//纯虚函数 Shape(int a,int b=0); }; Shape::Shape(int a,int b) { m_a = a; m_b = b; } class Square : public Shape { public: Square(int a,int b); double GetS(); }; Square::Square(int a,int b):Shape(a,b) { } double Square:: GetS() { return m_a*m_b; } class Circle : public Shape { public: Circle(int a); double GetS(); }; Circle::Circle(int a) : Shape(a) { } double Circle::GetS() { return 3.14*m_a*m_a; } int main() { Square s(2,3); cout<<"矩形的面积"<<s.GetS()<<endl; Circle c(2); cout<<"圆的面积"<<c.GetS()<<endl; Shape *p = new Square(3,3); cout<<"square: "<<p->GetS()<<endl; p = new Circle(4); cout<<"circle: "<<p->GetS()<<endl; return 0; }
答案
矩形的面积6
圆的面积12.56
square: 9
circle: 50.24
GetS()为虚函数,可以使基类指针调用派生类函数,根据对象类型决定调用的函数
#include<iostream> #include<cstring> using namespace std; class Animal { public: int m_age; public: Animal(int a); ~Animal(); }; Animal::Animal(int a) { cout<<"animal constructor"<<endl; m_age = a; } Animal::~Animal() { cout<<"animal dextructor"<<endl; } class Bird: virtual public Animal { public: int m_height; public: Bird(int h,int a); ~Bird(); }; Bird::Bird(int h,int a):Animal(a) { cout<<"bird constructor"<<endl; m_height = h; } Bird::~Bird() { cout<<"bird destructor"<<endl; } class Fish: virtual public Animal//虚继承 { public: int m_swim; public: Fish(int s,int a); ~Fish(); }; Fish::Fish(int s,int a):Animal(a) { cout<<"fish constructor"<<endl; m_swim = s; } Fish::~Fish() { cout<<"fish destructor"<<endl; } class Waterbird : public Bird,public Fish { public: char *m_name; public: Waterbird(int h,int s,char *n,int a); ~Waterbird(); void show(); }; Waterbird::Waterbird(int h,int s,char *n,int a):Bird(h,a),Fish(s,a),Animal(a)// { cout<<"waterbird constructor"<<endl; m_name = new char[10]; strcpy(m_name,n); } void Waterbird::show() { //cout<<" 高度 "<<m_height<<" 速度 "<<m_swim<<" 年龄 "<<Fish::m_age<<" 名字 "<<m_name<<endl; cout<<" 高度 "<<m_height<<" 速度 "<<m_swim<<" 年龄 "<<m_age<<" 名字 "<<m_name<<endl;//虚继承解决二义性问题 } Waterbird::~Waterbird() { cout<<"waterbird destructor"<<endl; if(m_name!=NULL) { delete [] m_name; } } int main() { Waterbird b(12,22,"bird",111); b.show(); cout<<"&b "<<&b<<endl; cout<<"&b.m_height "<<&b.m_height<<endl; cout<<"&b.m_swim "<<&b.m_swim<<endl; cout<<"&b.m_age "<<&b.m_age<<endl;//地址顺序:虚基类指针 m_height 虚基类指针 m_swim m_name m_age Bird *pb = &b; Fish *pf = &b; Animal *pa = &b; Waterbird *pw = &b; //pb.m_height = 1; //pb.m_age = 1; cout<<"pb: "<<pb<<endl; cout<<"pf: "<<pf<<endl; cout<<"pa: "<<pa<<endl; cout<<"pw: "<<pw<<endl; cout<<"pb+1: "<<pb+1<<endl; cout<<"pf+1: "<<pf+1<<endl; cout<<"pa+1: "<<pa+1<<endl; cout<<"pw+1: "<<pw+1<<endl; return 0; }animal constructor
bird constructor
fish constructor
waterbird constructor
高度 12 速度 22 年龄 111 名字 bird
&b 0xbfe88a48
&b.m_height 0xbfe88a4c
&b.m_swim 0xbfe88a54
&b.m_age 0xbfe88a5c
pb: 0xbfe88a48
pf: 0xbfe88a50
pa: 0xbfe88a5c
pw: 0xbfe88a48
pb+1: 0xbfe88a54
pf+1: 0xbfe88a5c
pa+1: 0xbfe88a60
pw+1: 0xbfe88a60
waterbird destructor
fish destructor
bird destructor
animal dextructor