不可或缺 Windows Native (22) - C++: 多重继承, 虚基类

[源码下载]

作者:webabcd

介绍
不可或缺 Windows Native 之 C++

  • 多重继承
  • 虚基类

示例
1、基类 1
CppBase1.h

#pragma once 

#include <string>
#include "CppBaseVirtual.h"

using namespace std;

namespace NativeDll
{
    // virtual 代表 CppBaseVirtual 是 CppBase1 的虚基类(虚基类是在声明派生类时,指定继承方式时声明的)
    class CppBase1 : virtual public CppBaseVirtual
    {

    protected:
        string Name;
        float Salary;

    public:
        CppBase1(int number, string name, float salary);

    };
}

CppBase1.cpp

/*
 * 基类 1
 */

#include "pch.h"
#include "CppBase1.h" 

using namespace NativeDll;

CppBase1::CppBase1(int number, string name, float salary) :CppBaseVirtual(number), Name("cppbase1 " + name), Salary(salary)
{

}

2、基类 2
CppBase2.h

#pragma once 

#include <string>
#include "CppBaseVirtual.h"

using namespace std;

namespace NativeDll
{
    // virtual 代表 CppBaseVirtual 是 CppBase2 的虚基类(虚基类是在声明派生类时,指定继承方式时声明的)
    class CppBase2 : virtual CppBaseVirtual
    {

    protected:
        string Name;
        int Age;

    public:
        CppBase2(int number, string name, int age);

    };
}

CppBase2.cpp

/*
 * 基类 2
 */

#include "pch.h"
#include "CppBase2.h" 

using namespace NativeDll;

CppBase2::CppBase2(int number, string name, int age) :CppBaseVirtual(number), Name("cppbase2 " + name), Age(age)
{

}

3、虚基类
CppBaseVirtual.h

#pragma once 

#include <string>

using namespace std;

namespace NativeDll
{
    class CppBaseVirtual
    {

    private:
        int Number;

    public:
        CppBaseVirtual(int number);

    };
}

CppBaseVirtual.cpp

/*
 * 用于演示虚基类
 *
 * 注:
 * 1、虚基类并不是在声明基类时声明的,而是在声明派生类时,指定继承方式时声明的
 * 2、一个基类可以在生成一个派生类时作为虚基类,也可以在生成一个派生类时不作为虚基类
 */

#include "pch.h"
#include "CppBaseVirtual.h" 

using namespace NativeDll;

CppBaseVirtual::CppBaseVirtual(int number) :Number(number)
{

}

4、派生类
CppDerived.h

#pragma once 

#include <string>
#include "CppBase1.h"
#include "CppBase2.h"

using namespace std;

namespace NativeDll
{
    class CppDerived : public CppBase1, public CppBase2
    {

    public:
        CppDerived(int number, string name, float salary, int age);

        string Show();

    };
}

CppDerived.cpp

/*
 * 派生类
 *
 *
 * 在多重继承的情况下:
 * 1、如果 A 是 B C D E 的基类,F 同时继承了 B C D E,那么实例化 F 时会保存 4 份 A 成员
 * 2、如果 A 是 B 的基类,A 是 C D E 的虚基类(虚基类会使得在继承间接共同基类时只保留一份成员),F 同时继承了 B C D E,那么实例化 F 时会保存 2 份 A 成员(从 C D E 的路径上保留一份,从 B 的路径上保留一份)
 *
 *
 * 本例中:
 * 1、CppBaseVirtual 是 CppBase1 和 CppBase2 的虚基类
 * 2、CppDerived 继承了 CppBase1 和 CppBase2(多重继承)
 * 3、此种情况,实例化 CppDerived 只会保留一份 CppBaseVirtual 成员(因为 CppBaseVirtual 是 CppBase1 和 CppBase2 的虚基类)
 * 4、C++ 编译器只会执行最后的派生类(CppDerived)对虚基类(CppBaseVirtual)的构造函数的调用,而忽略虚基类的直接派生类(CppBase1 和 CppBase2)对虚基类的构造函数的调用,这就保证了虚基类的数据成员不会被多次初始化
 */

#include "pch.h"
#include "CppDerived.h"
#include "cppHelper.h"

using namespace NativeDll;

// 在无虚基类的情况下,派生类的构造函数中只需负责对其直接基类初始化
// 如果有虚基类,且虚基类中定义了带参数的构造函数,且没有定义默认构造函数,那么派生类不仅要负责对其直接基类进行初始化,还要负责对虚基类初始化
CppDerived::CppDerived(int number, string name, float salary, int age) :CppBaseVirtual(number), CppBase1(number, name, salary), CppBase2(number, name, age)
{

}

string CppDerived::Show()
{
    // 关于多重继承的二义性(ambiguous),如果派生类同时继承的多个基类有相同的成员,则调用这些成员时需显式指定其基类
    return CppBase1::Name + " " + float2string(Salary) + " " + int2string(Age);

    // 另外:当然,如果派生类与多个基类有相同成员的话,那么基类中的这些与派生类相同的成员都会被隐藏掉(即派生类中的成员会覆盖基类中的成员)
}

5、示例
CppClass6.h

#pragma once 

#include <string>

using namespace std;

namespace NativeDll
{
    class CppClass6
    {
    public:
        string Demo();
    };
}

CppClass6.cpp

/*
 * 多重继承(multiple inheritance), 虚基类(virtual base class)
 */

#include "pch.h"
#include "CppClass6.h"
#include "CppDerived.h" 

using namespace NativeDll;

string CppClass6::Demo()
{
    CppDerived derived(0, "webabcd", 100.0f, 35);
    string result = derived.Show(); // cppbase1 webabcd 100.00 35

    return result;
}

OK
[源码下载]

时间: 2025-01-01 10:27:00

不可或缺 Windows Native (22) - C++: 多重继承, 虚基类的相关文章

不可或缺 Windows Native (20) - C++: 友元函数, 友元类

[源码下载] 作者:webabcd 介绍不可或缺 Windows Native 之 C++ 友元函数 友元类 示例演示友元函数, 友元类CppClass4.h #pragma once #include <string> using namespace std; namespace NativeDll { class CppClass4 { public: string Demo(); }; } CppClass4.cpp /* * 友元(friend)函数, 友元类 * * 友元函数: C+

不可或缺 Windows Native 系列文章索引

[源码下载] 作者:webabcd 1.不可或缺 Windows Native (1) - C 语言: hello c 介绍不可或缺 Windows Native 之 C 语言 在 Windows Store Apps 中调用 C/C++ hello c 2.不可或缺 Windows Native (2) - C 语言: 常量,变量,基本数据类型 介绍不可或缺 Windows Native 之 C 语言 常量 变量 基本数据类型 3.不可或缺 Windows Native (3) - C 语言:

不可或缺 Windows Native (23) - C++: 虚函数

[源码下载] 作者:webabcd 介绍不可或缺 Windows Native 之 C++ 虚函数 示例1.基类CppHuman.h #pragma once #include <string> using namespace std; namespace NativeDll { class CppHuman { protected: string Name; public: // 我是虚函数 virtual string Show(); // 我是纯虚函数(后面的“=0”只起形式上的作用,用

虚基类练习:动物(利用虚基类建立一个类的多重继承,包括动物(animal,属性有体长,体重和性别),陆生动物(ter_animal,属性增加了奔跑速度),水生动物(aqu_animal,属性增加了游泳速度)和两栖动物(amp_animal)。)

Description 长期的物种进化使两栖动物既能活跃在陆地上,又能游动于水中.利用虚基类建立一个类的多重继承,包括动物(animal,属性有体长,体重和性别),陆生动物(ter_animal,属性增加了奔跑速度),水生动物(aqu_animal,属性增加了游泳速度)和两栖动物(amp_animal).其中两栖动物保留了陆生动物和水生动物的属性. Input 两栖动物的体长,体重,性别,游泳速度,奔跑速度(running_speed) Output 初始化的两栖动物的体长,体重,性别,游泳速度

不可或缺 Windows Native (7) - C 语言: 指针

[源码下载] 作者:webabcd 介绍不可或缺 Windows Native 之 C 语言 指针 示例cPointer.h #ifndef _MYHEAD_POINTER_ #define _MYHEAD_POINTER_ #ifdef __cplusplus extern "C" #endif char *demo_cPointer(); #endif cPointer.c /* * 指针 */ #include "pch.h" #include "c

不可或缺 Windows Native (24) - C++: 运算符重载, 自定义类型转换

[源码下载] 作者:webabcd 介绍不可或缺 Windows Native 之 C++ 运算符重载 自定义类型转换 示例CppOperator.h #pragma once #include <string> using namespace std; namespace NativeDll { class CppOperator { public: string Demo(); }; } CppOperator.cpp /* * 运算符重载, 自定义类型转换 */ #include &qu

不可或缺 Windows Native (18) - C++: this 指针, 对象数组, 对象和指针, const 对象, const 指针和指向 const 对象的指针, const 对象的引用

[源码下载] 不可或缺 Windows Native (18) - C++: this 指针, 对象数组, 对象和指针, const 对象,  const 指针和指向 const 对象的指针, const 对象的引用 作者:webabcd 介绍不可或缺 Windows Native 之 C++ this 指针 对象数组 对象和指针 const 对象 const 指针和指向 const 对象的指针 const 对象的引用 示例1.CppEmployee 类CppEmployee.h #pragma

不可或缺 Windows Native (14) - C++: 文件

[源码下载] 作者:webabcd 介绍不可或缺 Windows Native 之 C++ 文件 示例CppIO2.h #pragma once #include <string> using namespace std; namespace NativeDll { class CppIO2 { public: string Demo(string rootPath); }; } CppIO2.cpp /* * 文件 */ #include "pch.h" #include

不可或缺 Windows Native (12) - C++: 引用类型

[源码下载] 作者:webabcd 介绍不可或缺 Windows Native 之 C++ 引用类型 示例CppReference.h #pragma once #include <string> using namespace std; namespace NativeDll { class CppReference { public: string Demo(); }; } CppReference.cpp /* * 引用类型 * * 引用也可以称之为“别名” * * 注: * 1.声明引