程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 不可或缺 Windows Native (21),native21

不可或缺 Windows Native (21),native21

編輯:C++入門知識

不可或缺 Windows Native (21),native21


[源碼下載]


不可或缺 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
[源碼下載]

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved