dimanche 30 septembre 2018

Issue with getting values from polymorphic objects

The function that needs to be fixed is int getCValue(A *pa).

Right now the output I'm getting is * * 5 16 when it should be * * 5 7.

What is causing this to be incorrect? I need to return the value of the c-object if C or D are not NULL. I think that this may be because multiple objects are being initialized thus changing the value that the C-object holds but I don't know how to prevent this.

#include <iostream>
#include <stdexcept>
using namespace std;
struct A {
  A(int n) : _value(n) {}
  virtual ~A(void) {}
  virtual int value(void) { return _value; }
private:
  int _value;
};


struct B : A {
  B(int m, int n) : A(m), _value(n) {}
  ~B(void) override {}
  int value(void) override { return A::value() + _value; }
private:
  int _value;
};


struct C : A {
  C(int n) : A(n) {}
  ~C(void) override {}
  int value(void) override { return A::value() + 2; }
};


struct D : B, C {
  D(int m, int n) : B(m, n), C(n) {}
  ~D(void) override {}
  int value(void) override { return B::value() + C::value(); }
};

/////////////////////////////////////////////////////////////////
A *createD(int m, int n)
{
  D* newD = new D(m, n);
  C* newC = newD;
  A* newA = newC;
  return newA;
}

int getCValue(A *pa)
{
  C* c = dynamic_cast<C*>(pa);
  D* d = dynamic_cast<D*>(pa);

  if (c != NULL || d != NULL)
  {
    int check = c->value();
    return check;
  }
  else
  {
    throw std::runtime_error("whoa");
  }
}
/////////////////////////////////////////////////////////////////
int main(void) {

  A *pa = createD(2, 3);
  int value = pa->value();
  cout << "expected: 10" << endl;
  cout << "     got: " << value << endl;
  delete pa;
  cout << endl;

  A *array[] = { new A(0), new B(1,2), new C(3), createD(4,5) };
  cout << "expected: * * 5 7" << endl;
  cout << "     got: ";
  for (A *pa : array) {
    try {
      cout << getCValue(pa) << ' ';
    }
    catch (exception &e) {
      cout << '*' << ' ';
    }
  }
  for (A *pa : array)
    delete pa;
  cout << endl;

  return 0;
}

Aucun commentaire:

Enregistrer un commentaire