簡體   English   中英

多態:從基類數組訪問派生類元素

[英]Polymorphism: accessing derived class elements from a base class array

我有一段時間沒有使用派生類和多態,我無法弄清楚如何訪問派生類數據項。

// Quick example
class Base {
  string data1;  // data1 = "FOO"
};
class ChildA : public Base {
  string data2;
};


int main() {
Base **list;
list = new Base*[1];
base[0] = new ChildA(// data2 = "BAR");
std::cout << base[0]->data1; // FOO
std::cout << base[0]->data2; // Error; no member named "data2" in Base

是否可以從基類數組中檢索派生數據?

當您通過指向基類的指針查看派生類的實例時,您只能看到基類的成員,因為通常,您不會知道您正在查看的子類型實例。 多態和虛函數的關鍵在於,在許多情況下,您可以使用子類型實例而無需了解其實際類型。 例如,如果要打印有關實例的信息,並且希望在打印ChildA時包含data2 ,則可以在Base創建虛擬toString()函數,並在ChildA覆蓋它以包含data2 然后,您可以在不知道實際類型的情況下調用toString() ,如果您的實例實際上是ChildA ,您將獲得data2

默認情況下,類成員變量是私有的。 通過使用基類指針,您無法獲得派生類成員var。

如果您願意這樣做,您可能希望實現虛擬getter函數,它將幫助您從派生類獲取私有成員函數。

如果基類接口必須具有可能保存在派生類中的數據的知識,那么這是少數幾種非常危險的方法之一。

#include <iostream>
#include <vector>
#include <utility>
#include <memory>
#include <stdexcept>

using namespace std;

class Base {
public:
    Base(std::string d1 = {"FOO"} ) : _data1 { std::move(d1) } {}
    virtual ~Base() = default; // because polymorphism without a virtual base class is naughty
    const string& data1() const { return _data1; }

    virtual bool has_data2() const { return false; }
    virtual const string& data2() const {
        throw invalid_argument {"I don't have data2"};
    };

private:
    string _data1;  // data1 = "FOO"
};

class ChildA : public Base {
public:
    ChildA(std::string d2, std::string d1 = {"FOO"})
    : Base { std::move(d1) }
    , _data2 { std::move(d2) }
    {}

    bool has_data2() const override { return true; }
    const std::string& data2() const override {
        return _data2;
    };

private:
    string _data2;
};

int main()
{
    vector<unique_ptr<Base>> bases;
    bases.push_back(unique_ptr<Base>(new ChildA("bob")));
    bases.push_back(unique_ptr<Base>(new Base("not foo")));

    for(const auto& p : bases) {
        cout << p->data1() << ", " << (p->has_data2() ? p->data2() : "no data 2") << endl;
    }

    return 0;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM