Connecting Tech Pros Worldwide Help | Site Map

virtual casting

Herby
Guest
 
Posts: n/a
#1: Mar 27 '06
Given class B and C which inherit from class A
They all override a method of the form:
Add( A^ lhs, A^ rhs ); So A is abstract.

So if i was defining Add for class B :


B::Add( A^ lhs, A^ rhs )
{
Value = ((B)lhs)->Value + ((B)rhs)->Value;
}

And the rhs argument happens to be of type C, although mostly it would
be of type B.
Instances of type C can legally be cast( converted ) to instances of
type B.

Given the argument is of type A, and the actual instance can be either
B or C.
How can i cast rhs to B?

I tried adding a virtual and concrete operatorB*() to A and C,
but made no difference?

Any ideas greatly appreciated?

Jakob Bieling
Guest
 
Posts: n/a
#2: Mar 27 '06

re: virtual casting


Herby <prmarjoram@gmail.com> wrote:[color=blue]
> Given class B and C which inherit from class A
> They all override a method of the form:
> Add( A^ lhs, A^ rhs ); So A is abstract.[/color]

A^? I have seen that in some Microsoft specific CLI code. This is
*not* C++!
[color=blue]
> So if i was defining Add for class B :
>
>
> B::Add( A^ lhs, A^ rhs )
> {
> Value = ((B)lhs)->Value + ((B)rhs)->Value;
> }[/color]

Why not just pass references to B objects? Then you would not have
to cast here at all.
[color=blue]
> And the rhs argument happens to be of type C, although mostly it would
> be of type B.
> Instances of type C can legally be cast( converted ) to instances of
> type B.[/color]

Then I guess they could be implicitly casted to "references to B".
Considering the above remark, you could pass B and C objects now
[color=blue]
> Given the argument is of type A, and the actual instance can be either
> B or C.
> How can i cast rhs to B?[/color]

You can't. If all you have is A, then there is no way to pretend it
to be a B.

hth
--
jb

(reply address in rot13, unscramble first)


Herby
Guest
 
Posts: n/a
#3: Mar 27 '06

re: virtual casting


Firstly please substitute ^ for *. Am currently running this problem
against C++\CLI, but is more general to C++.

The problem is the client only has pointers to A*
and it does not know if they are B or C instances..

Ideally i would define

B::Add( B* lhs, C* rhs )
{
// now works
static_cast<B*>(rhs)
// given in class C i have defined operatorB*()
// like a string class converting itself to a double given thats
what it text contains
}

and at runtime given these are the types of the instances, then this
would be the method called.
But its not - its linked to the A* A* method.

I thought it would be possible by defining a virtual cast operator in A
but it is not called? I do not understand why not?

If its really not possible i need this confirmed and then go back to
the drawing board.

Thanks.

Jakob Bieling
Guest
 
Posts: n/a
#4: Mar 27 '06

re: virtual casting


Herby <prmarjoram@gmail.com> wrote:[color=blue]
> Firstly please substitute ^ for *. Am currently running this problem
> against C++\CLI, but is more general to C++.
>
> The problem is the client only has pointers to A*
> and it does not know if they are B or C instances..[/color]

I do not really know what your inheritance tree looks like, but I am
assuming the following:

class A {};

class B : public A { int Value; };

class C : public B {};
[color=blue]
> Ideally i would define
>
> B::Add( B* lhs, C* rhs )[/color]

Given the above, you can just have:

B* B::Add( B* lhs, B* rhs );

without the need or operator B* ().
[color=blue]
> {
> // now works
> static_cast<B*>(rhs)
> // given in class C i have defined operatorB*()[/color]

'operator B* ()' has nothing to do with this. You are casting the
pointer, and not applying 'operator B*()' to the *object*.
[color=blue]
> // like a string class converting itself to a double given thats
> what it text contains
> }
>
> and at runtime given these are the types of the instances, then this
> would be the method called.
> But its not - its linked to the A* A* method.[/color]

Did you make "Add" virtual? Are you calling "Add" on an object of
type A or A? You really need to provide more details. Please post
minimal code that I can compile or at least try to compile so that I get
the error you are getting.
[color=blue]
> I thought it would be possible by defining a virtual cast operator in
> A but it is not called? I do not understand why not?
>
> If its really not possible i need this confirmed and then go back to
> the drawing board.[/color]

hth
--
jb

(reply address in rot13, unscramble first)


Bob Hairgrove
Guest
 
Posts: n/a
#5: Mar 27 '06

re: virtual casting


On 27 Mar 2006 05:19:29 -0800, "Herby" <prmarjoram@gmail.com> wrote:
[color=blue]
>Given class B and C which inherit from class A
>They all override a method of the form:
>Add( A^ lhs, A^ rhs ); So A is abstract.
>
>So if i was defining Add for class B :
>
>
>B::Add( A^ lhs, A^ rhs )
>{
> Value = ((B)lhs)->Value + ((B)rhs)->Value;
>}
>
>And the rhs argument happens to be of type C, although mostly it would
>be of type B.[/color]

You left out a very important detail: what is the type of the return
value for Add()? You cannot instantiate an object of type A because A
is abstract. Therefore, you cannot return an object of type A.

However, you cannot return a reference to A because Value is computed
within the function, and you must not return references or pointers to
local objects.

???

--
Bob Hairgrove
NoSpamPlease@Home.com
Daniel T.
Guest
 
Posts: n/a
#6: Mar 27 '06

re: virtual casting


In article <1143465569.561774.319180@i39g2000cwa.googlegroups .com>,
"Herby" <prmarjoram@gmail.com> wrote:
[color=blue]
> Given class B and C which inherit from class A
> They all override a method of the form:
> Add( A^ lhs, A^ rhs ); So A is abstract.
>
> So if i was defining Add for class B :
>
>
> B::Add( A^ lhs, A^ rhs )
> {
> Value = ((B)lhs)->Value + ((B)rhs)->Value;
> }[/color]

Normally, 'Add' adds two numbers together. However, the function above
takes three parameters (one of which you oddly don't use.) I can't help
wondering why you did that... Is that some special definition in the
language you are using?

If this were written in C++, then I would tell you to either make this a
non-member function or remove one of the parameters.
[color=blue]
> And the rhs argument happens to be of type C, although mostly it would
> be of type B.
> Instances of type C can legally be cast( converted ) to instances of
> type B.[/color]

Then why have type C? Just make everything a B and be done with it.

[color=blue]
> Given the argument is of type A, and the actual instance can be either
> B or C.
> How can i cast rhs to B?[/color]

You can't. Let me be more clear, you *can* do it (reinterpret_cast)
however doing so is a bad decision.
[color=blue]
> I tried adding a virtual and concrete operatorB*() to A and C,
> but made no difference?
>
> Any ideas greatly appreciated?[/color]

Try moving Value into class A and making your Add method global (not a
member-function.)

Of course, my advice only applies to C++, so it may not have any value
to you in the language you are using.


--
Magic depends on tradition and belief. It does not welcome observation,
nor does it profit by experiment. On the other hand, science is based
on experience; it is open to correction by observation and experiment.
Herby
Guest
 
Posts: n/a
#7: Mar 27 '06

re: virtual casting


Guys thanks for the great response. I have been posting this into the
C++\CLI forum and not getting any replies.
Im a little concerned as it may imply i have still some fundamentals to
understand about casting and virtual functions etc.

So i will now provide you with some minimal classes and share my
problem with you:


class A
{
public:
virtual void Add( A* lhs, A* rhs )=0;
};

---------------------------------------------------------

class B : public A
{
public:

B( String* value){Value = value;};
virtual void Add( A* lhs, A* rhs );

operator C*() { // converts string value to double given it contains
something like "1008.790" :};

String* Value;
};

// Assume here that String comes from common base library could be
CString or std::string etc
-------------------------------------------------------------------

public ref class C : public A
{
public:

C( double value ){ Value = value; };

virtual void Add( A* lhs, A* rhs )
{
Value = static_cast<C*>(lhs)->Value +
static_cast<C*>(rhs)->Value;
// here i assumed the cast operator would be called on rhs -
whereby it would return itself as an object of B*
}

double Value;
};

So Value cannot go into base class as is a different type in all the
subclasses of A.
And C does not inherit from B, is a sibling of C.

Some client code:

int main()
{
C* c = new C(515.18);
B* b = new B("50");

A* lhs = c;
A* rhs = b;

C* c2 = new C(100); // this will recieve the new value

c2->Add(lhs, rhs);

}

So the Add is applied to an object and the value computed is assigned
to this object.
Dont worry about this part of it though.

Just how can i assign a value of C to B, when using a pointer to A ?
More precisly

lhs = (C*)rhs;

Where rhs is currently pointer to A*.

Is this possible - it feels like it should be?
If not why not? why can i not define a virtual cast to C* jn A ?

Thanks.

Daniel T.
Guest
 
Posts: n/a
#8: Mar 27 '06

re: virtual casting


In article <1143474423.678519.18410@g10g2000cwb.googlegroups. com>,
"Herby" <prmarjoram@gmail.com> wrote:
[color=blue]
> Guys thanks for the great response. I have been posting this into the
> C++\CLI forum and not getting any replies.
> Im a little concerned as it may imply i have still some fundamentals to
> understand about casting and virtual functions etc.[/color]
[color=blue]
> virtual void C::Add( A* lhs, A* rhs )
> {
> Value = static_cast<C*>(lhs)->Value +
> static_cast<C*>(rhs)->Value;
> // here i assumed the cast operator would be called on rhs -
> whereby it would return itself as an object of B*
> }[/color]

Not at all, the casting operator isn't in A. I recommend that you put a
virtual member_function in A that returns the value as a double. Then:

class A {
public:
virtual double DoubleVal() const = 0;
};

double B::DoubleVal() const {
/* convert the string and returns a double */
}

void B::Add( A* lhs, A* rhs ) {
double tmp = lhs->DoubleVal() + rhs->DoubleVal();
/* convert tmp into a string and assign to Value */
}

double C::DoubleVal() const { return Value; }

void C::Add( A* lhs, A* rhs ) {
Value = lhs->DoubleVal() + rhs->DoubleVal();
}

Give up on the casting operator already...


--
Magic depends on tradition and belief. It does not welcome observation,
nor does it profit by experiment. On the other hand, science is based
on experience; it is open to correction by observation and experiment.
Herby
Guest
 
Posts: n/a
#9: Mar 28 '06

re: virtual casting


Well done Daniel, you have solved my problem.
I knew there was a simple solution to all this. That works well.
Thanks.

Closed Thread


Similar C / C++ bytes