[英]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.