3

请考虑以下代码:

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

我尝试了以下方法,但它们对我不起作用并给出错误“从'超类*'转换为非标量类型'子类'请求”和“从'超类*'转换为非标量类型'subclass2'请求”

    subclass s1=r.superman[0];
    subclass2 s2=r.superman[1];

我确定我错过了一些小东西。

PS:我找不到类似的问题,但如果存在,请重定向我,我也想要一个不需要我使用向量或任何内置的预先存在的库类的解决方案。

4

3 回答 3

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 函数访问数据,不要将成员声明为 public。

于 2013-01-15T09:05:41.067 回答
1
    superclass **superman;
    runner()
    {
        *superman=...

这几行代码为代码提供了未定义的行为。您不能取消引用未初始化的指针并期望一切正常。

于 2013-01-15T09:06:32.833 回答
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]);
//...

注意:从基类转换为派生类时要小心。并且不要忘记释放分配的内存。

于 2013-01-15T09:44:59.043 回答