虚函数继承和虚继承是完全不同的两个概念。
虚函数继承是解决多态性的,当用基类指针指向派生类对象的时候,基类指针调用虚函数的时候会自动调用派生类的虚函数,这就是多态性,也叫动态编联。可以说是针对成员函数问题,使得基类指针可以使用各自派生类的成员函数而不造成冲突。
虚继承就是为了节约内存,他是多重继承中的特有的概念。适用于菱形继承形式,可以说是针对同一个基类继承下来的同一个成员对象的冲突问题。
#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