浅谈C++|类的继承篇

这篇具有很好参考价值的文章主要介绍了浅谈C++|类的继承篇。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

 浅谈C++|类的继承篇,c++,算法,开发语言

引子: 

继承是面向对象三大特性之一、有些类与类之间存在特殊的关系,例如下图中:

浅谈C++|类的继承篇,c++,算法,开发语言

我们发现,定义这些类时,下级别的成员除了拥有上一级的共性,还有自己的特性。
这个时候我们就可以考虑利用继承的技术,减少重复代码。

一.继承基本语法 

语法:class 子类:继承方式 父类 

优点:减少重复代码

子类也叫派生类,父类也叫基类

代码: 

#include <iostream>
using namespace std;
class person {   //定义person基类
public:
	int age;
	int height;
	int weight;
	string name;

	void show() {
		cout << "age=" << age << endl;
		cout << "height=" << height << endl;
		cout << "weight=" << weight << endl;
		cout << "name=" << name << endl;
	}
};

class women :public person {
public:
	string xingbie;
	void shou_x() {
		cout << "xingbie=" << xingbie<<endl;
	}
};

void fun() {
	women p;
	p.age = 18;
	p.height = 180;
	p.name = "tom";
	p.weight = 160;
	p.xingbie = "女";
	p.show();
	p.shou_x();
}
int main() {
	fun();
	return 0;
}

浅谈C++|类的继承篇,c++,算法,开发语言

 派生类中的成员,包含两大部分:
1.类是从基类继承过来的,-类是自己增加的成员。
2.从基类继承过过来的表现其共性,而新增的成员体现了其个性。

 二.继承方式

 继承方式:

public:     公有继承

protected:保护继承

private:    私有继承

代码:

#include <iostream>
using namespace std;
class father {
public:
	int A;
protected:
	int B;
private:
	int C;
};

class son1 :public father {    //公有继承
public:
	void fun() {
		cout << "A=" << A << endl;  //公有变为公有
		cout << "B=" << B << endl;  //保护变为保护
		//cout << "C=" << C << endl;//私有不可访问
	}
};

class son2 :protected father {    //保护继承
public:
	void fun() {
		cout << "A=" << A << endl;  //公有变为保护
		cout << "B=" << B << endl;  //保护变为保护
		//cout << "C=" << C << endl;//私有不可访问
	}
};


class son3 :private father {    //私有继承
public:
	void fun() {
		cout << "A=" << A << endl;  //公有变为私有
		cout << "B=" << B << endl;  //保护变为私有
		//cout << "C=" << C << endl;//私有不可访问
	}
};


void fun() {
	son1 p1;
	son2 p2;
	son3 p3;
	p1.A = 10;
	p1.fun();
}
int main() {
	fun();
	return 0;
}

浅谈C++|类的继承篇,c++,算法,开发语言

 私有成员全不见,公不变,保全保,私全私。

 三.继承中的对象模型

继承中,基类私有变量虽然访问不到,但是已经被继承,只是被隐藏了。

 代码:

#include <iostream>
using namespace std;
class father {
public:
	int A;
protected:
	int B;
private:
	int C;
};
class son :private father {
public:
	int age;
};
int main() {
	cout << sizeof(son) << endl;
	return 0;
}

四.继承构造和析构顺序

子类继承父类时,会先创建一个父类。析构的顺序和构造顺序正好相反。

 代码:

#include <iostream>
using namespace std;
class father {
public:
	father() {
		cout << "father的构造哈数" << endl;
	}
	~father() {
		cout << "father的析构函数" << endl;
	}
};
class son :public father {
public:
	son() {
		cout << "son的构造函数" << endl;
	}
	~son() {
		cout << "son的析构函数" << endl;
	}
};
void fun() {
	son a;
}
int main() {
	fun();
	return 0;
}

浅谈C++|类的继承篇,c++,算法,开发语言

五.继承同名成员处理方式

当基类中的成员变量以及成员函数,和派生类的成员变量和函数重名时,基类默认调用派生类的成员函数和成员变量。要想调用基类的成员函数和成员变量,需要加上基类的作用域;

代码:

#include <iostream>
using namespace std;
class father {
public:
	int A;
	father() {
		A = 999;
	}
	void fun() {
		cout << "father的fun调用" << endl;
	}
	void fun(int a) {
		cout << "father的fun调用" << ' ' << a << endl;
	}
};
class son :public father{
public:
	int A;
	son() {
		A = 99;
	}
	void fun() {
		cout << "son的fun调用" << endl;
	}
	void fun(int a) {
		cout << "father的fun调用" << ' ' << a << endl;
	}
};
void fun() {
	son p;
	cout << "son" << ' ' << p.A << endl;
	cout << "father" << ' ' << p.father::A << endl;
	p.fun();
	p.fun(11);
	p.father::fun();
	p.father::fun(90);
}
int main() {
	fun();
	return 0;
}

 如果派生类中出现和基类重名的成员函数,那么派生类会隐藏基类全部重名的成员函数。需要注意的是,本来可以按照函数重载区分,却被派生类隐藏的情况:

代码: 

#include <iostream>
using namespace std;
class father {
public:
	int A;
	father() {
		A = 999;
	}
	
	void fun() {
		cout << "father的fun调用" << endl;
	}
	void fun(int a,int b) {
		cout << "father的fun调用" << ' ' << a << endl;
	}
};
class son :public father{
public:
	int A;
	son() {
		A = 99;
	}
	void fun() {
		cout << "son的fun调用" << endl;
	}
};
void fun() {
	son p;
	cout << "son" << ' ' << p.A << endl;
	cout << "father" << ' ' << p.father::A << endl;
	p.fun();
	p.fun();
	p.father::fun();
	//p.fun(90,89);//报错
	p.father::fun(89, 123);
}
int main() {
	fun();
	return 0;
}

六.继承同名static成员处理方式

 当重名的成员变量和函数是static时,需要注意通过类名来调用的方式

代码:

#include <iostream>
using namespace std;
class father {
public:
	static int A;
	static void fun() {
		cout << "father的fun调用" << endl;
	}
	void fun(int a) {
		cout << "father的fun调用" << a<<' ' << endl;
	}
};
int father::A=10;   //static成员变量,类内声明,类外定义
class son :public father {
public:
	static int A;
	static void fun() {
		cout << "son的fun调用" << endl;
	}
};
int son::A = 20;
void fun() {
	son p;
	//1.利用对象调用成员变量和函数
	cout << p.A << endl;
	cout << p.father::A << endl;
	p.fun();
	p.father::fun();

	cout << "**************************" << endl;
	//2.利用类名调用成员变量和函数
	cout << son::A << endl;
	cout << father::A << endl;
	cout << son::father::A << endl;   

	son::fun();
	father::fun();
	son::father::fun();    
	//father::fun(10);  //报错,此方法只能调用static类型


}
int main() {
	fun();
	return 0;
}

浅谈C++|类的继承篇,c++,算法,开发语言

七.多继承语法

C++中允许一个类继承多个类


语法: class子类∶继承方式父类1,继承方式父类2...


多继承可能会引发父类中有同名成员出现,需要加作用域区分
C++实际开发中不建议用多继承

 代码:

#include <iostream>
using namespace std;
class base1 {
public:
	int A;
	base1() {
		A = 10;
		cout << "base1构造函数调用" << endl;
	}
};


class base2 {
public:
	int A;
	base2() {
		A = 20;
		cout << "base2构造函数调用" << endl;
	}
};

class son :public base1, public base2 {
public:
	int B;
	int C;
	son() {
		B = 100;
		C = 200;
		cout << "son构造函数调用" << endl;
	}
};

void fun() {
	son b;
	cout << b.base1::A << endl;
	cout << b.base2::A << endl;
	cout << b.B << endl;
	cout << b.C << endl;
}
int main() {
	fun();
	return 0;
}

 浅谈C++|类的继承篇,c++,算法,开发语言

 注意构造函数的调用顺序,父亲1先调用,父亲2再调用,最后son调用

总结:多继承中如果父类中出现了同名情况,子类使用时候要加作用域。

八.菱形继承

菱形继承概念:
两个派生类继承同一个基类
又有某个类同时继承者两个派生类
这种继承被称为菱形继承,或者钻石继承

浅谈C++|类的继承篇,c++,算法,开发语言

1.羊继承了动物的数据,驼同样继承了动物的数据,当羊驼使用数据时,就会产生二义性。
2.羊驼将动物的数据继承了两份,其实我们应该清楚,这份数据我们只需要—份就可以。

 代码:

#include <iostream>
using namespace std;
class dongwu {
public:
	int A;
};
class yang :public dongwu {};
class tuo:public dongwu {};
class son :public tuo, public yang {};
void fun() {
	son p;
	p.yang::A = 100;
	p.tuo::A = 200;
	//当菱形继承,两个父亲拥有相同名的成员时,要加作用域加以区分;
	cout << p.yang::A << endl;
	cout << p.tuo::A << endl;
}
int main() {
	fun();
	return 0;
}

浅谈C++|类的继承篇,c++,算法,开发语言

此时的继承情况是,这样的。 

浅谈C++|类的继承篇,c++,算法,开发语言

 利用虚继承,可以解决菱形继承的问题(两份相同的数据,浪费内存)

代码:

#include <iostream>
using namespace std;
class dongwu {
public:
	int A;
};
//virtual虚继承,dongwu称为虚基类
class yang :virtual public dongwu {};
class tuo:virtual public dongwu {};
class son :public tuo, public yang {};
void fun() {
	son p;
	yang p1;
	tuo p2;
	p.yang::A = 100;
	p.tuo::A = 200;
	p1.A = 90;
	p2.A = 190;
	//当菱形继承,两个父亲拥有相同名的成员时,要加作用域加以区分;
	cout << p.yang::A << endl;
	cout << p.tuo::A << endl;
	cout << p1.A << endl;
	cout << p2.A << endl;

}
int main() {
	fun();
	return 0;
}

浅谈C++|类的继承篇,c++,算法,开发语言

 继承时只继承一份,此时son继承的是两个虚基类表的指针,虚基类表中存储的是到成员的偏移量。

总结:
·菱形继承带来的主要问题是子类继承两份相同的数据,导致资源浪费以及毫无意义·利用虚继承可以解决菱形继承问题文章来源地址https://www.toymoban.com/news/detail-731679.html

到了这里,关于浅谈C++|类的继承篇的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C++ 类的继承

    class 子类名 :继承方式  父类名 继承方式:public:  protected: private: 特点:         不管哪种方式继承,都不印象子类对父类成员的访问权限,即除了private成员其他都可访问;         类外只能访问public方式继承的父类的公共区成员。

    2024年02月10日
    浏览(25)
  • Python类的继承

    一、类的继承 众所周知,Python是面向对象编程。而面向对象编程主要好处之一便是代码的重用。Python实现代码重用的方法之一是通过继承。 继承是类和类之间的一种关系,是一种子类和父类的关系。如子类继承父类,而Python类中重要的两个东西便是属性和方法。那么Python的

    2024年01月25日
    浏览(26)
  • 继承类的方法

    1 问题 定义一个父类,用子类去继承父类所拥有的方法、定义属性,然后使用测试文件实现子类输出父类的方法信息,属性等。 2 方法 2.1 定义一个名为Person的父类: 2.2 定义一个名为Student的子类,并令其继承父类: 2.3 定义父类的属性、方法: 2.4定义子类的属性,以及输出

    2024年02月08日
    浏览(30)
  • [C#基础训练]类的继承

    参考代码:

    2024年02月06日
    浏览(28)
  • Python趣味入门14:类的继承

    小牛叔带你轻松飞越Python类的门槛 继承最好的示例竟然是病毒复制。类似于COVID-19病毒全球肆虐,病毒复制变异的过程就是下一代继承上一代部分特性,并发展出新特性的过程(如下图)。 病毒的变异来源于DNA(RNA)蛋白质突变 因此编程中的继承,也具有如下两个特征: 复制

    2024年02月03日
    浏览(28)
  • Python中类的继承细讲

      在编写类时,并不是每次都要从空白开始。当要编写的类和另一个已经存在的类之间 存在一定的继承关系 时,就可以 通过继承来达到代码重用 的目的,提高开发效率。下面将介绍如何在 Python 中实现 继承 。    继承 是 面向对象编程最重要的特性之一 ,它源于人们认

    2024年02月06日
    浏览(27)
  • 实验三 Java类的继承与派生

    Student IStudentDAO StudentDAOImpl MainClass

    2024年02月05日
    浏览(41)
  • 如何用IDEA查看一个类的所有继承关系

    最近在研究集合的继承关系图,在网上查的都不是很全,所以就想能不能直接看jar包里面的以来关系,在网上查了一下方法,总结如下: 工具:idea 功能:diagram 在你想查看的类内,点击右键,选择 Diagrams,其中有 show Diagrams和 show Diagrams Popup,前者新建在标签页内,后者以浮

    2024年02月04日
    浏览(32)
  • Python面向对象编程(一)类的基础,关系,继承,封装,多态

    类的一些理论概念及其应用场景等基础内容此处不赘述 目录 python中一切皆对象 类的定义及基础 属性 方法 初始化方法  普通方法 类之间的关系 相互调用 依赖关系 关联关系 组合关系 三大特征----类的继承 重写父类方法 多继承 混合继承  三大特征----封装 三大特征----多态

    2024年02月10日
    浏览(67)
  • 类的继承和super关键字的使用(JAVA)

    目录 继承 super   子类的构造方法 final 所有的OOP语言都会有三个特征: 封装(点击可跳转) 继承 多态(点击可跳转) 为什么会有继承呢?可以先看下面的例子:         上面这两个类中的代码很相似因为它们只有最后一个方法不同其它的都相同,这样定义不但导致代码

    2024年02月14日
    浏览(30)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包