C++ 中的物件切片

Jinku Hu 2021年6月28日
C++ 中的物件切片

本文將介紹 C++ 中的物件切片。

在 C++ 中使用物件切片將派生類物件轉換為基類

物件導向程式設計的核心概念是繼承,這意味著類可以相互關聯並形成層次結構。層次結構的根通常稱為基類,其他類從該基類繼承資料成員或函式形式的特徵。從其他類繼承的類稱為派生類。有不同型別的繼承來指定對基類成員的訪問控制,以及在派生類中可以訪問哪些成員。例如,不能直接從派生類訪問基類的私有成員。相反,派生類應該使用 public 方法來檢索這些成員。基類可以指定一組單獨的成員,並帶有可從派生類直接訪問的受保護識別符號。

在這種情況下,我們關注派生到基礎的轉換規則以及此類功能的用例。通常,派生類包含在派生類本身中定義的非靜態成員以及從其他類繼承的所有成員。當派生物件被分配給基類物件時,賦值運算子 run 取自基類。因此,這個運算子只知道基類成員,並且只有那些成員在賦值操作期間被複制。

#include <iostream>

using std::cout; using std::cin;
using std::endl; using std::string;

class Person {
protected:
    string name;

public:
    explicit Person(string s): name(std::move(s)) {}

    string getName() { return name; };
};

class Athlete : public Person {
    string sport;
public:
    explicit Athlete(string s) : Person(std::move(s)) {};
    Athlete(string s, string sp) :
            Person(std::move(s)), sport(std::move(sp)) {};

    string getSport() { return sport;}

};

class Politician : public Person {
    string party;
public:
    explicit Politician(string s) : Person(std::move(s)) {}
    Politician(string s, string p) :
            Person(std::move(s)), party(std::move(p)) {}

    string getParty() { return party;}

};

int main()  {
    Politician p1("Lua", "D");
    Athlete a1("Lebron", "LA Lakers");

    cout << p1.getName() << " " << p1.getParty() << endl;

    Person p0 = p1;
    Athlete a2(p0.getName());

    cout << p0.getName() << endl;
    cout << a2.getName() << endl;

    return EXIT_SUCCESS;
}

輸出:

Lua D
Lua

前面的示例程式碼定義了從 Person 類派生的兩個類,PoliticianAthlete。因此,我們可以將 Politician 物件分配給 Person,而不是另一種方式。分配完成後,在新建立的 p0 物件中無法訪問成員函式 getParty。因此,以下版本的程式碼會導致編譯時錯誤,因為 p0 呼叫了 Politician 類的成員。

#include <iostream>

using std::cout; using std::cin;
using std::endl; using std::string;

class Person {
protected:
    string name;

public:
    explicit Person(string s): name(std::move(s)) {}

    string getName() { return name; };
};

class Athlete : public Person {
    string sport;
public:
    explicit Athlete(string s) : Person(std::move(s)) {};
    Athlete(string s, string sp) :
            Person(std::move(s)), sport(std::move(sp)) {};

    string getSport() { return sport;}

};

class Politician : public Person {
    string party;
public:
    explicit Politician(string s) : Person(std::move(s)) {}
    Politician(string s, string p) :
            Person(std::move(s)), party(std::move(p)) {}

    string getParty() { return party;}

};

int main()  {
    Politician p1("Lua", "D");
    Athlete a1("Lebron", "LA Lakers");

    cout << p1.getName() << " " << p1.getParty() << endl;

    Person p0 = p1;
    Politician p2 = p0;
    Politician p2 = a1;

    cout << p0.getName() << " " << p0.getParty() << endl;

    return EXIT_SUCCESS;
}
Author: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn

相關文章 - C++ Class