virtual casting 
March 27th, 2006, 12:35 PM
| | | virtual casting
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? | 
March 27th, 2006, 12:45 PM
| | | 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) | 
March 27th, 2006, 01:15 PM
| | | 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. | 
March 27th, 2006, 01:35 PM
| | | 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) | 
March 27th, 2006, 01:35 PM
| | | 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 | 
March 27th, 2006, 02:15 PM
| | | 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. | 
March 27th, 2006, 02:55 PM
| | | 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. | 
March 27th, 2006, 10:45 PM
| | | 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. | 
March 28th, 2006, 08:15 AM
| | | 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. | | Thread Tools | Search this Thread | | | |
Posting Rules
| You may not post new threads You may not post replies You may not post attachments You may not edit your posts HTML code is Off | | | | | | What is Bytes?
We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights.
Get the best answers to your questions from over 220,662 network members.
|