我暂时没有使用派生类和多态,我无法弄清楚如何访问派生类数据项。
// 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
是否可以从基类数组中检索派生数据?
答案 0 :(得分:3)
当您通过指向基类的指针查看派生类的实例时,您只能看到基类的成员,因为通常,您不会知道您的子类型实例是什么正在看。多态和虚函数的关键在于,在许多情况下,您可以使用子类型实例而无需了解其实际类型。例如,如果要打印有关实例的信息,并且希望在打印data2
时包含ChildA
,则可以在toString()
中创建虚拟Base
函数并在ChildA
中覆盖它以包含data2
。然后,您可以在不知道实际类型的情况下致电toString()
,如果您的实例实际上是ChildA
,那么您将获得data2
。
答案 1 :(得分:0)
默认情况下,类成员变量是私有的。 通过使用基类指针,您无法获得派生类成员var。
如果您愿意,可能需要实现虚拟getter函数,它将帮助您从派生类中获取私有成员函数。
答案 2 :(得分:0)
如果基类接口必须知道可能存在于派生类中的数据,那么这是少数几种非常危险的方法之一。
#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;
}