2

I have the following situation

class B {
public:
    B() {};
    virtual ~B() {};
    virtual void seti( int x ) { i = x; };
    virtual void setj( int x ) { j = x; };
    virtual void add() =0;

protected:
    int i;
    int j;
};
class D :  public B {
public:
 virtual void add() { cout << "D-add:" << i + j << endl; }; 
};

class E: public B {
public:
    void seti( int x ) { i = x; };
    void add() { cout << "E-add:" << i + j << endl; }; 
    void mult() { cout << "E-mult:" << i * j << endl; }; 
};

int _tmain(int argc, _TCHAR* argv[])
{
    D *d = new D();
    d->seti(4); d->setj(5); d->add();
    E*e = d;
    e->seti(8); e->add(); e->mult();
    return 0;
}
I get the following error
1>.\CallBack.cpp(38) : error C2440: 'initializing' : cannot convert from 'D *' to 'E *'
1> Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-styl`enter code here`e cast

What i want to do is when I instantiate E, I was use all the information / members of D and do some thing more with it. Should I use hierarchical inheritance like above or should I use multi-level inheritance or is there any other better way. Please advise. Thank you !

Amol
  • 43
  • 5
  • like static members? http://stackoverflow.com/questions/1390913/are-static-variables-in-a-base-class-shared-by-all-derived-classes – corn3lius Jun 06 '12 at 18:45

5 Answers5

3

You could change

class E: public B {

to

class E: public D {
Ed Heal
  • 59,252
  • 17
  • 87
  • 127
2

I think what you want is a "conversion ctor" - a constructor on E which takes a reference/pointer to D as the parameter and populates itself basing on D's values. To copy fields defined on B, you can do this:

class B {
public:
....
  B(B& source) { this->i = source.i; this->j = source.j; }
....
}
class E {
public:
....
  E(D& source) : B(source) { // no need to do anything about i,j
  }
....
}

Also, you can write a converter class (DtoEConverter) which will have a function to do that.

Mr. TA
  • 5,230
  • 1
  • 28
  • 35
  • Agree conversion constructor is one way...but that will force me to write some function like " int getj(){ return j; }". Is there any way other than not writing any "get" functions ? – Amol Jun 06 '12 at 19:26
  • Of course there is... Define a "copy ctor" on B, and call that from your conversion ctor on E. In the copy ctor of B, your i and j can be copied directly, without get functions. – Mr. TA Jun 06 '12 at 19:32
  • can you please provide me a sample code ? will greatly appreciate it...thank you for the response – Amol Jun 06 '12 at 20:00
2
D *d = new D();
d->seti(4); d->setj(5); d->add();
E*e = d;

d is a pointer-to D. You can't assign a pointer-to D to a variable that takes a pointer-to E because the types are not directly related.

They are related at the base class, but d is not an E, and that's the problem you're having.

You could do this:

B* e = d;

Becasue d is a B.

By the way, your question title asks:

How can two derived objects of same base class communicate?

Emphasis mine. You don't have two derived objects -- you only have one. There are two classes, but you only ever instantiate one actual object, here:

 D *d = new D();
John Dibling
  • 99,718
  • 31
  • 186
  • 324
  • Thanks! I made a slight update to code above. I want to use all the data saved in 'd' and do another operation (say multiply as in the edited code above). – Amol Jun 06 '12 at 19:23
1

I am not a C++ programmer however, I wish to try and provide an alternative based on what we might do in C sharp

You could potentially add interface to Class D....say interface IAdd and then pass Class D into Class E.

So in the constructor of Class E you could have something like: public E(Interface x) .... pass in class D instead of X.

Please let me know if this helps :)

Regards

Bull
  • 701
  • 1
  • 6
  • 13
1

Rather than pollute your main classes with inter-class communication, introduce a new class.

class DECommunicator
{
public:
  DECommunicator(D* dPtr, E* ePtr)
  {
    mDPtr = dPtr;
    mEPtr = ePtr;
  }

  void DSetI(int x)
  {
    mDPtr->setI(x);
  }

  // add additional methods to allow D to "talk" to E and vice versa

private:
  D* mDPtr;
  E* mEPtr;
}

Difficult to give code as I am not really sure what you are trying to achieve, given your example.