请考虑以下代码:
#include <iostream>
using namespace std;
class superclass;
class subclass;
class subclass2;
class superclass
{
public:
unsigned int a;
superclass **superman;
};
class subclass : public superclass
{
public:
unsigned int b;
};
class subclass2 : public superclass
{
public:
unsigned int b;
};
class runner
{
public:
superclass **superman;
runner()
{
*superman=new superclass[2];
superman[0]=new subclass;
superman[0]->a=3;
superman[1]=new subclass2;
superman[1]->a=4;
}
};
int main() {
runner r;
cout<<r.superman[0]->a<<" "<<r.superman[1]->a;
return 0;
}
正如您所看到的,我想创建一个动态分配的父类引用存储,然后每个类都可以指向子类,但我怎么不知道如何从该数组中再次提取子类,所以我可以访问其变量b;
我尝试了以下方法,但它们没有为我工作并给出错误 “从'超类*'转换为非标量类型'子类''请求”和 “从'超类*'转换为非标量类型'子类2'请求”
subclass s1=r.superman[0];
subclass2 s2=r.superman[1];
我确信我错过了一些小事。
PS:我找不到类似的问题,但如果它存在,请重定向我, 我也想要一个不需要我使用矢量或任何内置的解决方案 预先存在的图书馆类。
答案 0 :(得分:2)
在这种情况下,您确实需要智能指针,而超类不需要指向自身的指针。你可以将超类指针存储在指向真实派生类的向量中,这样多态性仍然可以工作:
#include <memory>
#include <vector>
struct superclass
{
public:
superclass() : a(0) {}
virtual ~superclass() {} // it's important to define virtual destructor as superclass is a base class
int getA() const { return a; }
private:
unsigned int a;
};
class subclass : public superclass
{
public:
unsigned int b;
};
class subclass2 : public superclass
{
public:
unsigned int b;
};
class runner
{
public:
std::vector<std::unique_ptr<superclass>> superman;
runner()
{
superman.emplace_back(new subclass());
superman.emplace_back(new subclass2());
}
};
然后你可以简单地访问它:
int main()
{
runner r;
std::cout << r.superman[0]->getA() <<" " < <r.superman[1]->getA();
return 0;
}
附注:如果可以,隐藏数据,通过set / get函数访问数据,不要将成员声明为公共数据。
答案 1 :(得分:1)
superclass **superman;
runner()
{
*superman=...
这几行代码为代码提供了未定义的行为。你不能取消引用一个未初始化的指针,并期望一切正常。
答案 2 :(得分:1)
在virtual
中添加superclass
析构函数并使用dynamic_cast
:
class superclass
{
public:
unsigned int a;
superclass **superman;
virtual ~superclass(){}; // You must at least have one virtual method
// in your superclass and destructor is good choice
// Otherwise, dynamic_cast wouldn't work:
// error: ... (source type is not polymorphic) !
};
// ...
// s1 and s2 must be pointers:
subclass *s1=dynamic_cast<subclass* >(r.superman[0]);
subclass2 *s2=dynamic_cast<subclass2*>(r.superman[1]);
//...
注意:注意从基类转换为派生类。并且不要忘记释放已分配的内存。