Sfoglia il codice sorgente

上传文件至 '继承2'

Creamo 2 anni fa
parent
commit
6e506632c0

+ 92 - 0
继承2/5、继承同名成员处理方式.cpp

@@ -0,0 +1,92 @@
+//4.6.5   继承同名成员处理方式
+
+//问题:当子类与父类出现同名的成员,如何通过子类对象,访问到子类或父类中同名的数据呢?
+
+//⚪访问子类中的同名成员  直接访问即可
+//⚪访问父类中的同名成员  需要加作用域
+
+
+
+#include <iostream>
+
+
+class Base
+{
+public:
+	Base()
+	{
+		m_A = 100;
+	}
+
+	void func()
+	{
+		std::cout << "Base - func()调用" << std::endl;
+	}
+
+	void func(int a)
+	{
+		std::cout << "Base - func(int a)调用" << std::endl;
+	}
+
+	int m_A;
+};
+
+class Son :public Base
+{
+public:
+	Son()
+	{
+		m_A = 200;
+	}
+
+	void func()
+	{
+		std::cout << "Son - func()调用" << std::endl;
+	}
+
+	int m_A;
+};
+
+
+void test01()
+{
+	Son s;
+	std::cout << "Son m_A = " << s.m_A << std::endl;
+	//如果通过子类对象  访问到父类中同名成员,需要加作用域
+	std::cout << "Base m_A = " << s.Base::m_A << std::endl;
+}
+
+
+//同名成员函数处理
+void test02()
+{
+	Son s;
+	s.func();      //直接调用  调用的是子类中的同名成员
+
+	//如何调用到父类中的同名成员函数?
+	s.Base::func();
+
+	//如果子类中出现了和父类中同名的成员函数,子类的同名成员会隐藏掉父类中所有同名成员函数
+	//如果想访问到父类中被隐藏的童名成员函数,需要加作用域
+	s.Base::func(100);
+}
+
+int main()
+{
+	//test01();
+	
+	test02();
+
+	system("pause");
+
+	return 0;
+}
+
+
+
+
+
+//总结:
+//1、子类对象可以直接访问到子类中的同名成员      s.m_A
+//2、子类对象加作用域可以访问到父类同名成员      s.Base::m_A
+//3、当子类与父类拥有同名的成员函数,子类会隐藏父类中同名成员函数,加作用域可以访问到父类中同名函数     

+ 96 - 0
继承2/6、继承同名静态成员处理方式.cpp

@@ -0,0 +1,96 @@
+//4.6.6    继承同名静态成员处理方式
+
+//问题:继承中同名静态成员在子类对象上如何进行访问?
+
+
+//静态成员和非静态成员出现同名,处理方式一致
+
+//⚪访问子类同名成员   直接访问即可
+
+//⚪访问父类同名成员   需要加作用域
+
+
+
+#include <iostream>
+
+
+class Base
+{
+public:
+	static int m_A;
+
+	static void func()
+	{
+		std::cout << "Base - static void func()" << std::endl;
+	}
+	static void func(int a)
+	{
+		std::cout << "Base - static void func(int a)" << std::endl;
+	}
+};
+
+int Base::m_A = 100;
+
+class Son :public Base
+{
+public:
+	static int m_A;
+
+	static void func()
+	{
+		std::cout << "Son - static void func()" << std::endl;
+	}
+};
+
+int Son::m_A = 200;
+
+//同名静态成员属性
+void test01()
+{
+	//1、通过对象访问
+	std::cout << "通过对象访问" << std::endl;
+	Son s;
+	std::cout << "Son m_A = " << s.m_A << std::endl;
+	std::cout << "Base m_A = " << s.Base::m_A << std::endl;
+
+	//2、通过类名访问
+	std::cout << "通过类名访问" << std::endl;
+	std::cout << "Son m_A = " << Son::m_A << std::endl;
+	//第一个::代表通过类名方式访问   第二个::代表通过父类作用域下的 m_A
+	std::cout << "Base m_A = " << Son::Base::m_A << std::endl;
+}
+
+//同名静态成员函数
+void test02()
+{
+	//1、通过对象访问
+	std::cout << "通过对象访问" << std::endl;
+	Son s;
+	s.func();
+	s.Base::func();
+
+	//2、通过类名访问
+	std::cout << "通过类名访问" << std::endl;
+	Son::func();
+	Son::Base::func();
+	
+	//子类出现和父类同名静态成员函数,也会隐藏父类中所有同名成员函数
+	//如果想访问父类中被隐藏同名成员,需要加作用域
+
+	Son::Base::func(100);
+}
+
+int main()
+{
+	//test01();
+	test02();
+
+
+	system("pause");
+
+	return 0;
+}
+
+
+
+//同名静态成员处理方式和非静态处理方式一样,只不过有两种访问的方式(通过对象 和 通过类名)

+ 74 - 0
继承2/7、多继承语法.cpp

@@ -0,0 +1,74 @@
+//4.6.7    多继承语法
+
+//C++允许一个类继承多个类
+
+//语法:class 子类:继承方式 父类1 , 继承方式 父类2...
+
+//多继承可能会引发父类中有同名成员出现,需要加作用域区分
+
+//C++实际开发中不建议使用多继承
+
+
+
+
+#include <iostream>
+
+
+class Base1
+{
+public:
+	Base1()
+	{
+		m_A = 100;
+	}
+
+	int m_A;
+};
+
+class Base2
+{
+public:
+	Base2()
+	{
+		m_A = 200;
+	}
+
+	int m_A;
+};
+
+//子类  需要继承Base1 和 Base2
+class Son :public Base1, public Base2
+{
+public:
+	Son()
+	{
+		m_C = 300;
+		m_D = 400;
+	}
+
+	int m_C;
+	int m_D;
+};
+
+void test01()
+{
+	Son s;
+	std::cout << "sizeof Son = " << sizeof(Son) << std::endl;
+	//当父类中出现同名成员  需要加作用域区分
+	std::cout << "Base1::m_A = " << s.Base1::m_A << std::endl;
+	std::cout << "Base2::m_B = " << s.Base2::m_A << std::endl;
+}
+
+int main()
+{
+	test01();
+
+	system("pause");
+
+	return 0;
+
+}
+
+
+
+//多继承中如果父类中出现了同名情况,子类使用的时候要加作用域

+ 90 - 0
继承2/8、菱形继承.cpp

@@ -0,0 +1,90 @@
+//4.6.8     菱形继承
+
+//菱形继承概念:
+
+//两个派生类继承同一个基类
+
+//又有某个类同时继承这两个派生类
+
+//这种继承被称为菱形继承,或者钻石继承
+
+//     动  物
+// 🐏         🐫
+//     草泥马 
+
+
+//菱形继承的问题:
+
+//1、🐏继承了动物的数据,🐫同样继承了动物的数据,当草泥马使用数据时,就会产生二义性
+//2、草泥马继承自动物的数据继承了两份,其实我们应该很清楚,这份数据我们只需要一份就可以
+
+
+
+#include <iostream>
+
+//动物类
+class Animal
+{
+public:
+	int m_Age;
+};
+
+
+//利用虚继承  可以解决菱形继承的问题
+//在继承前  加关键字  virtual 变为虚继承
+//Animal类称为  虚基类
+//vbptr  虚基类指针  ->  vbtable  虚基类表
+//v - virtual
+//b - base
+//ptr - pointer
+//继承了两个指针  指针通过偏移量找到唯一数据
+
+//羊类
+class Sheep :virtual public Animal
+{
+
+};
+
+//驼类
+class Tuo :virtual public Animal
+{
+
+};
+
+//羊驼类
+class SheepTuo : public Sheep, public Tuo
+{
+
+};
+
+
+void test01()
+{
+	SheepTuo st;
+	st.Sheep::m_Age = 18;
+	st.Tuo::m_Age = 28;
+	
+	//当出现菱形继承的时候,两个父类拥有相同的数据,需要加以作用域区分
+	
+	std::cout << "st.Sheep::m_Age = " << st.Sheep::m_Age << std::endl;
+	std::cout << "st.Tuo::m_Age = " << st.Tuo::m_Age << std::endl;
+	std::cout << "st.m_Age = " << st.m_Age << std::endl;
+
+	//这份数据我们知道 只要有一份就可以了  菱形继承导致数据有两份  资源浪费
+
+}
+
+int main()
+{
+	test01();
+
+
+	system("pause");
+
+	return 0;
+}
+
+
+//总结:
+//⚪菱形继承带来的主要问题时子类继承两份相同的数据,导致资源浪费以及毫无意义
+//⚪利用虚继承可以解决菱形继承问题