c++虚函数继承与虚继承(五)

原创 2018年04月17日 19:49:02



虚函数继承和虚继承是完全不同的两个概念。

虚函数继承是解决多态性的,当用基类指针指向派生类对象的时候,基类指针调用虚函数的时候会自动调用派生类的虚函数,这就是多态性,也叫动态编联。

虚继承就是为了节约内存,他是多重继承中的特有的概念。适用于菱形继承形式。

#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

关于C++虚继承、虚函数继承的几个例子

今天看虚继承以及虚函数继承时写了几个实例来加深一下理解。相关技术原理参见:c++虚继承对象的内存布局 代码1: 没有虚继承的情况下 #include using namespace std; clas...
  • memewry
  • memewry
  • 2012-08-04 20:58:46
  • 2007

C++ 虚继承和虚函数同时存在的对象模型

如果说没有虚函数的虚继承只是一个噩梦的话,那么这里就是真正的炼狱。这个C++中最复杂的继承层次在VC上的实现其实我没有完全理解,摸爬滚打了一番也算得出了微软的实现方法吧,至于一些刁钻的实现方式我也想不...
  • chengonghao
  • chengonghao
  • 2016-06-22 20:16:23
  • 1688

C++ 深入理解 虚继承、多重继承和直接继承

本文从5段代码实例出发,通过类中类的普通继承,类的虚继承,类的多重继承,多个虚函数类的普通继承、虚继承与多重继承,几个交叉概念,详细的阐释了继承、虚函数与虚继承的基本概念,深入剖析了继承于虚继承的区别...
  • u013630349
  • u013630349
  • 2015-07-25 16:54:24
  • 8214

C++虚继承虚基类虚函数纯虚函数总结

对于这些虚的,之前有很多歧义和不解,现在进行一下学习总结吧! 1.多重继承可能会导致二义性,而虚继承可以解决这个问题。虚继承是一种机制,类通过虚继承指出它希望共享其虚基类的状态,在虚继承下给定虚基类...
  • u011700461
  • u011700461
  • 2015-11-12 16:59:23
  • 637

C++之虚函数(三)虚继承和虚基类详解

多继承(Multiple Inheritance)是指从多个直接基类中产生派生类的能力,多继承的派生类继承了所有父类的成员。尽管概念上非常简单,但是多个基类的相互交织可能会带来错综复杂的设计问题,命名...
  • Bruce_0712
  • Bruce_0712
  • 2017-02-18 10:52:46
  • 504

C++中虚函数与纯虚函数以及虚继承的相关知识

这篇文章主要利用网上的博客,经过自己的总结写成,不免出现错误情况,如有错误,请指正。 虚函数 首先是虚函数的意义。在面向对象的设计思想中,虚函数的作用是实现多态性。如何实现多态呢?下面看C++虚函数表...
  • chy19911123
  • chy19911123
  • 2015-09-08 20:42:53
  • 1219

C++虚函数、虚继承、对象内存模型

一、虚函数的工作原理       虚函数的实现要求对象携带额外的信息,这些信息用于在运行时确定该对象应该调用哪一个虚函数。典型情况下,这一信息具有一种被称为 vptr(virtual table po...
  • hxz_qlh
  • hxz_qlh
  • 2013-11-09 00:48:47
  • 3231

C++中虚继承的作用及底层实现原理

虚继承和虚函数是完全无相关的两个概念。 虚继承是解决C++多重继承问题的一种手段,从不同途径继承来的同一基类,会在子类中存在多份拷贝。这将存在两个问题:其一,浪费存储空间;第二,存在二义性问题,通常可...
  • bxw1992
  • bxw1992
  • 2017-08-30 22:26:11
  • 5308

继承、 虚继承和虚函数表对类的大小的影响

一、真空类 class CNull { }; 长度:1 内存结构: ?? 评注:长度其实为0,这个字节作为内容没有意义,可...
  • u014744118
  • u014744118
  • 2016-03-30 23:27:28
  • 2692

C++虚继承与普通继承的区别

虚继承的时候在子类的对象中会多出一个叫虚类指针的大小,有的资料说这个指针指向的内存里面包含了该子类的偏移量和到基类的距离。但是我跟踪过这段内存,发现里面的数据没有规律,也找不到更多的支撑材料,权且先知...
  • bama2488313716
  • bama2488313716
  • 2015-04-16 15:54:17
  • 540
收藏助手
不良信息举报
您举报文章:c++虚函数继承与虚继承(五)
举报原因:
原因补充:

(最多只允许输入30个字)