We help IT Professionals succeed at work.

automatic casting?

nemitzan
nemitzan asked
on
Hi!  So say I have,

class A {blah blah}
class B (blah blah}

void MyFunc(A *input);

Also, I know A and B have the same data members, so I can safely go:

B *lala;
MyFunc((A*) lala);
Now what I want to do is overload some operator?? so that I don't need to cast a B* to an A*.  Ie:

MyFunc(lala);

Is there anyway for me to do this with operator overloading (or other way)? Or am I stuck with casting all the time?

Thanks in advance!
Comment
Watch Question

Use polymorphism, e.g:
Class CBase
{
public:
  DoThis(int i) = 0;
  DoThat(long j) = 0;
};

Class A : public CBase
{
  int m_nID;
  long m_nNumber;
public:
  //overide the methods of the base class
  DoThis(int i) {m_nID = i;}
  DoThat(long j) {m_nNumber = j*2;}
};

Class B : public CBase
{
  int m_nID;
  long m_nNumber;
public:
  //overide the methods of the base class
  //Different implementation then class A
  DoThis(int i) {m_nID = i-5;}
  DoThat(long j) {m_nNumber = j+3;}
};

The Global function gets pointer to CBase as parameter and the implementation can be sometgin like this for example:
void MyFunc(CBase *input)
{
  if(!input)
    return;
  input->DoThis(7);
  input->DoThat(2);
}

Now, just call the function and pass a pointer to one of the derived classes, e.g.:
A inputA;
B inputB;
MyFunc(&A); //no explicit casting
MyFunc(&B); //no explicit casting

The right version of the DoThis() & DoThat() functions will be called;

--EC--
AxterSenior Software Engineer

Commented:
>>Is there anyway for me to do this with operator
>>overloading

Sure.....

Example:
class A
{
public:
     A(int x) : m_x(x){}
     int m_x;
};

class B
{
public:
     B(int x) : m_x(x){}
     operator A()
     {
          return A(m_x);
     }
     int m_x;
};

void SomeFunction(A a)
{
     printf("%i",a.m_x);
}

void SomeOtherFunction(void)
{
     B b(33);
     SomeFunction(b);
}

Commented:
Add an operator A* in all your class (A&B),
class A/B
{
public:
   operator A* ( ) const
   {
     return (A*)this;
   };
   //...
};

then you can use this;
B *lala;
A *lala2;
MyFunc(*lala);
MyFunc(*lala2);

Commented:
Add an operator A* in all your class (A&B),
class A/B
{
public:
   operator A* ( ) const
   {
     return (A*)this;
   };
   //...
};

then you can use this;
B *lala;
A *lala2;
MyFunc(*lala);
MyFunc(*lala2);

> Add an operator A* in all your class (A&B),
> operator A* ( ) const
>  {
>   return (A*)this;
>  };

this is a recipe for potential disaster.  As soon as the classes get out of sync in any, possibly subtle (i.e. as soon as they are no longer POD structures) then this will fail silently - i.e. you will get no warning until some possibly unrelated piece of code crashes your program.

Avoid this.  Use either Axter's method or polymorphism to achieve your aims (if both classes really contain the same data, then that data can be pushed into the base class anyway).
 

Commented:
Agreed, the only acceptable answer was the suggestion from elcapitan and, to some degree, from Axter (his solution creates A /copies/ from B originals, different yet applicable in some cases.)

In general casting like you proposed should be regarded with a raised eyebrow or two, and used with great care. Hiding the dangerous behind the innocent looking facade of automatic conversion operator is a recipe for unsuspected disaster.

Commented:
jasonclarke, you are right.
But I think if nemitzan can ensure all the classes contain the same data, there no dangerous.
Of course Axter's method is also right, but if "MyFunc(A *input)" will change the value of input, Axter's method can't return the changed-value, because it only change a temp variable.

I think nemitzan can also overload the MyFunc;
i.e.
void MyFunc(A *input);
void MyFunc(B *input);
> But I think if nemitzan can ensure all
> the classes contain the same data

not true, adding a virtual function, or perhaps adding a data member that has a copy constructor could also result in failure.

This kind of cast is the worst kind of hack ... you are deliberately subverting the C++ type system.  

There are many ways to do this 'properly' including templates and inheritance/polymorphism.  

BTW, as an alternative templates are a relatively easy and safe solution to this particular problem:

template <typename T>
void MyFunc(T *input)
{
 if(!input)
   return;
 input->DoThis(7);
 input->DoThat(2);
}

Commented:
The suggestion from jasonclarke is an excellent one.  By writing this:

template <typename T>
void MyFunc(T *input)
{
    // (blah)
}

you can do anything to your input object (treat it as if it were an "A *", access its fields, call its virtual functions, call non-virtual functions, whatever.  The same template function will be instantiated when you call MyFunc with a "B *", except that it will do complete type checking at compile time.

So imagine that both classes have a member "x", and you write "input->x".  Even if the position of x within the two classes is different, the compiler will resolve them correctly.

Now imagine that A defines x, but B doesn't.  In that case, the compiler will issue a warning when you call MyFunc on a pointer of class B.

All of the concerns and issues raised above are answered by the template function.  Ain't life grand?

Commented:
I think you forgot this question. I will ask Community Support to close it unless you finalize it within 7 days. Unless there is objection or further activity,  I will suggest to accept "elcapitan" comment(s) as an answer.

If you think your question was not answered at all, you can post a request in Community support (please include this link) to refund your points.
The link to the Community Support area is: http://www.experts-exchange.com/commspt

PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!
======
Werner

Author

Commented:
Wow! Thanks all for the great suggestions!  For some reason I didn't get an email notify except for your last comment griessh.  Either that or they all got lost in the spam in my email box hrmmmm..
At any rate, sorry for the long delay accepting the answers, and thanks for the insight into the hidden disasters ;)

Author

Commented:
Wow! Thanks all for the great suggestions!  For some reason I didn't get an email notify except for your last comment griessh.  Either that or they all got lost in the spam in my email box hrmmmm..
At any rate, sorry for the long delay accepting the answers, and thanks for the insight into the hidden disasters ;)

Explore More ContentExplore courses, solutions, and other research materials related to this topic.