473,394 Members | 1,750 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,394 software developers and data experts.

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?

Mar 27 '06 #1
8 2045
Herby <pr********@gmail.com> wrote:
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.
A^? I have seen that in some Microsoft specific CLI code. This is
*not* C++!
So if i was defining Add for class B :
B::Add( A^ lhs, A^ rhs )
{
Value = ((B)lhs)->Value + ((B)rhs)->Value;
}
Why not just pass references to B objects? Then you would not have
to cast here at all.
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.
Then I guess they could be implicitly casted to "references to B".
Considering the above remark, you could pass B and C objects now
Given the argument is of type A, and the actual instance can be either
B or C.
How can i cast rhs to B?


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)
Mar 27 '06 #2
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.

Mar 27 '06 #3
Herby <pr********@gmail.com> wrote:
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..
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 {};
Ideally i would define

B::Add( B* lhs, C* rhs )
Given the above, you can just have:

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

without the need or operator B* ().
{
// now works
static_cast<B*>(rhs)
// given in class C i have defined operatorB*()
'operator B* ()' has nothing to do with this. You are casting the
pointer, and not applying 'operator B*()' to the *object*.
// 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.
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.
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.


hth
--
jb

(reply address in rot13, unscramble first)
Mar 27 '06 #4
On 27 Mar 2006 05:19:29 -0800, "Herby" <pr********@gmail.com> wrote:
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.


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
No**********@Home.com
Mar 27 '06 #5
In article <11**********************@i39g2000cwa.googlegroups .com>,
"Herby" <pr********@gmail.com> wrote:
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;
}
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.
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.
Then why have type C? Just make everything a B and be done with it.

Given the argument is of type A, and the actual instance can be either
B or C.
How can i cast rhs to B?
You can't. Let me be more clear, you *can* do it (reinterpret_cast)
however doing so is a bad decision.
I tried adding a virtual and concrete operatorB*() to A and C,
but made no difference?

Any ideas greatly appreciated?


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.
Mar 27 '06 #6
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.

Mar 27 '06 #7
In article <11*********************@g10g2000cwb.googlegroups. com>,
"Herby" <pr********@gmail.com> wrote:
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. 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*
}


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.
Mar 27 '06 #8
Well done Daniel, you have solved my problem.
I knew there was a simple solution to all this. That works well.
Thanks.

Mar 28 '06 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

6
by: Stuart Golodetz | last post by:
Hi, I've got a minor casting issue which I need to check about (marked // <--). I was trying to do a static_cast on it (which didn't work, though I'm not sure why this should be the case?) I...
4
by: aap | last post by:
Hi, I have the following code. #include <iostream> using namespace std; class Root { public: virtual void Root1() = 0; virtual void Root2() = 0;
5
by: zzppallas | last post by:
I have interface A and interface B decalared as follow: class A { public: virtual void OnError(std::string reson) = 0; }; class B { public:
2
by: Mike Stevenson | last post by:
Hi. I'm in the process of re-learning all the C++ I forgot from college, and I'm starting to get into some virgin (or at least only a couple times) territory. I have some questions about casting...
11
by: Nindi73 | last post by:
A few days a ago I posted my code for a deep copy pointer which doesn't require the pointee object to have a virtual copy constructor. I need help with checking that it was exception safe and...
2
by: Alex Vinokur | last post by:
classes that have virtual methods hold pointer to virtual table as additional implicit data member. So, sizeof of such classes is sizeof of all data (as struct-POD) plus 4. It seems that use of...
7
by: v4vijayakumar | last post by:
Is it possible to implement member object's virtual functions, in the containing class? If not, is it possible to simulate this behavior? ex: class test { protected: virtual void fun() = 0;...
7
by: Christopher Pisz | last post by:
My problem is my derived class is getting called twice instead of the base and then the derived. I thought this was the purpose for virtuals and dynamic casting :/ I want my base class to have its...
0
by: akshaycjoshi | last post by:
I am reading a book which says Even though unboxed value types don't have a type object pointer, you can still call virtual methods (such as Equals, GetHashCode, or ToString) inherited or...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.