Pregunta

I have a parent class which as a member contains an array of pointers to objects of the same type as itself. I have another class that derives from the parent class. I want that the derived class uses an array of pointers to objects of its own (not the parent class). The deriving class calls methods on those objects that are stored in the array of pointers; it calls both methods which are defined and implemented in the derived class as well as in the base class. The code below obviously doesn't compile as parent contains no member z (in derived::doX()). I could dyanamic_cast(p[i]).z before accessing z, but I would have to do that on EVERY method in b at runtime. If I hide "p" in the derived class (by casting the p's during object construction), I essentially get two arrays of pointers p, however, I want all methods operate on the same objects (residing in p). I tried templates but ran into a recursive issue. Any idea how to solve this?

#include <iostream>
#include <stdlib.h>
using namespace std;

class parent{
protected:
  parent** p;
  int num;
  int x;
public:
  parent(int _num, parent** _ps);
  virtual void doX();
  virtual void print();
};

class derived : public parent {
protected:
  //derived** p;
  int z;
public:
  derived(int _num, parent** _ps) : parent(_num, _ps){};
  virtual void doX();
  virtual void print();
};

void parent::doX(){
  for(int i=0;i<num;i++){
    p[i]->x = 1;
  }
}
void parent::print(){  cout << "x " << x << endl;
}

parent::parent(int _num, parent** _ds){
  num=_num;
  p = _ds;
}

void derived::doX(){
  for(int i=0;i<num;i++){
    p[i]->z = 2;
  }
  parent::doX();
}
void derived::print(){
  cout << "x " << x << endl;
  cout << "z " << z << endl;
}

int main(){
  const int NUM = 2;
  parent** ps = (parent**)malloc(sizeof(parent)*NUM);
  for(int i=0; i< NUM; i++){
    ps[i] = new derived(NUM, ps);
  }

  ps[0]->doX();
  ps[0]->print();
  ps[0]->print();
}
¿Fue útil?

Solución

You are on the right track! You should use the "p" defined in the parent class. In the derived class setter methods you enforce that the derived type must be used (as the parameter type). For instance your constructor for defined will be:

derived(int _num, derived** _ps) : parent(_num, _ps){};

Then, when you're using p in the derived methods, you know that p is really a derived type, and you can safely cast it.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top