不可或缺 Windows Native (21) - C++: 继承, 组合, 派生类的构造函数和析构函数, 基类与派生类的转换, 子对象的实例化, 基类成员的隐藏(派生类成员覆盖基类成员)
不可或缺 Windows Native (21) - C++: 继承, 组合, 派生类的构造函数和析构函数, 基类与派生类的转换, 子对象的实例化, 基类成员的隐藏(派生类成员覆盖基类成员)
作者:webabcd
介绍
不可或缺 Windows Native 之 C++
- 继承
- 组合
- 派生类的构造函数和析构函数
- 基类与派生类的转换
- 子对象的实例化
- 基类成员的隐藏(派生类成员覆盖基类成员)
示例
1、基类
CppAnimal.h
#pragma once #include <string> using namespace std; namespace NativeDll { class CppAnimal { private: int Number; protected: string Name; int Age; public: string Show(); CppAnimal(int number); }; }
CppAnimal.cpp
/* * 用于基类的演示 */ #include "pch.h" #include "CppAnimal.h" #include "cppHelper.h" using namespace NativeDll; string CppAnimal::Show() { return "animal: " + int2string(Number) + " " + Name; } CppAnimal::CppAnimal(int number) :Number(number) { Name = "动物"; }
2、派生类
CppTiger.h
#pragma once #include <string> #include "CppAnimal.h" #include "CppEmployee.h" using namespace std; namespace NativeDll { /* * 基类(base class) * 派生类(derived class) * 继承(inheritance) * 组合(composition) - 在一个类中以另一个类的对象作为数据成员的,称为类的组合 * * * public 继承:派生类不能访问基类的私有成员;基类的公有成员在派生类中依然是公有成员;基类的保护成员在派生类中依然是保护成员 * private 继承(默认值):派生类不能访问基类的私有成员;基类的公有成员在派生类中变为私有成员;基类的保护成员在派生类中变为私有成员 * protected 继承:派生类不能访问基类的私有成员;基类的公有成员在派生类中变为保护成员;基类的保护成员在派生类中依然是保护成员 */ class CppTiger : public CppAnimal // 我是 public 继承,这是最常用的 // class CppTiger : private CppAnimal // 我是 private 继承 // class CppTiger : protected CppAnimal // 我是 protected 继承 // class CppTiger : CppAnimal // 默认是 private 继承 { private: string NickName; // 在一个类中以另一个类的对象作为数据成员的,称为类的组合 CppEmployee employee; // 我是 CppTiger 的子对象(subobject) protected: // 派生类中的属性,如果其属性名与基类中的一样(不考虑属性的类型),则隐藏基类中的相应的属性(即派生类中的属性覆盖了基类中的属性) float Age; public: // 构造函数不会从基类继承过来,需要在派生类中自己写(注:析构函数也不会从基类继承过来,需要在派生类中自己写) CppTiger(int number); CppTiger(int number, string name, string nickName); // 用于演示如何在构造函数中,用简单的方式实例化子对象 CppTiger(int tigerNumber, string tigerName, int employeeNumber, string employeeName); // 派生类中的函数,如果其函数名和参数与基类中的一样(不考虑返回值类型),则隐藏基类中的相应的函数(即派生类中的函数覆盖了基类中的函数) string Show(); }; }
CppTiger.cpp
/* * 用于派生类的演示 */ #include "pch.h" #include "CppTiger.h" #include "cppHelper.h" using namespace NativeDll; // 在派生类的构造函数中调用基类的构造函数(注:在无虚基类的情况下,派生类的构造函数中只需负责对其直接基类初始化) CppTiger::CppTiger(int number) :CppAnimal(number) { } // 在派生类的构造函数中调用基类的构造函数,初始化派生类的私有成员 CppTiger::CppTiger(int number, string name, string nickName) :CppAnimal(number), NickName(nickName) { // 初始化基类的保护成员 Name = name; } // 在构造函数中,用简单的方式实例化子对象(本例实例化了 employee 对象) CppTiger::CppTiger(int tigerNumber, string tigerName, int employeeNumber, string employeeName) :CppAnimal(tigerNumber), employee(employeeNumber, employeeName) { // 如果用此种方式实例化子对象,则其实子对象会被实例化 2 次(声明时的 CppEmployee employee; 会被实例化一次,此处又会被实例化一次) // this->employee = CppEmployee(employeeNumber, employeeName); Name = tigerName; } // 我是 CppTiger 的 Show() 函数,由于与 CppAnimal 中的 Show() 函数同名且参数相同,所以 CppAnimal 中的 Show() 函数会被隐藏掉。也可以说 CppTiger 的 Show() 函数覆盖了 CppAnimal 中的 Show() 函数 string CppTiger::Show() { // 在派生类中调用基类成员的话,需要通过“::”来实现 // 本例中如果要调用基类的 Show() 的话,就这么写 CppAnimal::Show() // 如果直接调用 Show() 的话就死循环了 return "tiger: " + Name + ", employee: " + employee.Show() + ", " + CppAnimal::Show(); }
3、示例
CppClass5.h
#pragma once #include <string> using namespace std; namespace NativeDll { class CppClass5 { public: string Demo(); }; }
CppClass5.cpp
/* * 继承, 组合, 派生类的构造函数和析构函数, 基类与派生类的转换, 子对象的实例化, 基类成员的隐藏(派生类成员覆盖基类成员) */ #include "pch.h" #include "CppClass5.h" #include "CppTiger.h" using namespace NativeDll; string cppclass5_demo1(); string cppclass5_demo2(); void cppclass5_demo3(); string CppClass5::Demo() { string r1 = cppclass5_demo1(); string r2 = cppclass5_demo2(); string result = r1 + "\n" + r2; // 基类与派生类的转换 cppclass5_demo3(); return result; } string cppclass5_demo1() { // 此处演示了派生类的构造函数 CppTiger tiger(100, "老虎", "大猫"); // 此处演示了基类成员的隐藏(派生类成员覆盖基类成员) string result = tiger.Show(); // tiger: 老虎, employee: 888 webabcd, animal: 100 老虎 return result; } string cppclass5_demo2() { // 此处演示了派生类的构造函数,以及同时实例化子对象 CppTiger tiger2(100, "老虎", 200, "wanglei"); // 此处演示了基类成员的隐藏(派生类成员覆盖基类成员) string result = tiger2.Show(); // tiger: 老虎, employee: 200 wanglei, animal: 100 老虎 return result; } // 基类与派生类的转换 void cppclass5_demo3() { // 派生类对象可以赋值给基类对象(反之不可),基类对象无法使用派生类对象的特性 CppTiger tiger(100, "老虎", 200, "wanglei"); CppAnimal animal = tiger; // 调用的是基类的 Show() 函数(但是数据成员是通过 CppTiger 实例化而来的) string result = animal.Show(); // animal: 100 老虎 // 指向基类对象的指针,也可以指向派生类对象(反之不可),但是无法使用派生类对象的特性 CppAnimal animal2(100); CppAnimal *animal2Pointer = &animal2; CppTiger tiger2(200, "老虎", 300, "wanglei"); animal2Pointer = &tiger2; // 调用的是基类的 Show() 函数(但是数据成员是通过 CppTiger 实例化而来的) string result2 = animal2Pointer->Show(); // animal: 200 老虎 }
OK
[源码下载]