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;
}