473,406 Members | 2,377 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,406 software developers and data experts.

dynamic_cast for down casting from base to concrete type

Hello Everyone,

I just wanted to check that I'm using dynamic_cast correctly. I have a
hierarchy of objects using pure virtual classes and virtual inheritance
to implement interfaces. I ran into a problem using C-style casting to
an instance of a derived class from its interface type to a variable of
its concrete type. I was confused because I thought C-style casts
always compiled even if they wouldn't run correctly at runtime. I
modified the code to use dynamic_cast which seems correct, compiles and
runs but have found some contradictory information about its use so I
wanted to confirm I'm using it correctly. The code below illustrates
my problem. Thanks for your help.
#include <stdio.h>

class IObject
{
public:
virtual bool Equals(IObject *object) = 0;

};

class IList : public virtual IObject
{
public:
virtual IObject *Get(int index) = 0;
};

class Object : public virtual IObject
{
public:
virtual bool Equals(IObject *object) {
return this == object;
}
};

class ArrayList : public Object, public virtual IList
{
public:
virtual IObject *Get(int index) {
return this; // Just return something
}
};

class String : public Object { };
int main(int argc, char *argv[])
{
IList *list = new ArrayList();
IObject *obj = new String();
String *str = (String *)obj;
// This works: String *str = dynamic_cast<String *>(obj);
printf("str %s null.\n\0", str == 0 ? "is" : "is not");

}

Example.cpp: In function 'int main(int, char**)':
Example.cpp:39: error: cannot convert from base 'IObject' to derived
type 'String' via virtual base 'IObject'

Oct 29 '06 #1
5 2985
In article <11*********************@m7g2000cwm.googlegroups.c om>,
"mijobee" <mi*****@mijobee.comwrote:
Hello Everyone,

I just wanted to check that I'm using dynamic_cast correctly. I have a
hierarchy of objects using pure virtual classes and virtual inheritance
to implement interfaces. I ran into a problem using C-style casting to
an instance of a derived class from its interface type to a variable of
its concrete type. I was confused because I thought C-style casts
always compiled even if they wouldn't run correctly at runtime. I
modified the code to use dynamic_cast which seems correct, compiles and
runs but have found some contradictory information about its use so I
wanted to confirm I'm using it correctly. The code below illustrates
my problem. Thanks for your help.
#include <stdio.h>
#include <cstdio>
#include "String.h" // wherever this class is...
>
class IObject
{
public:
virtual ~IObject() { }
virtual bool Equals(IObject *object) = 0;

};

class IList : public virtual IObject
{
public:
virtual IObject *Get(int index) = 0;
};

class Object : public virtual IObject
{
public:
virtual bool Equals(IObject *object) {
return this == object;
}
};

class ArrayList : public Object, public virtual IList
{
public:
virtual IObject *Get(int index) {
return this; // Just return something
}
};

class String : public Object { };
int main(int argc, char *argv[])
{
IList *list = new ArrayList();
IObject *obj = new String();
String *str = (String *)obj;
The above doesn't work because Object derives from IObject virtually.
// This works: String *str = dynamic_cast<String *>(obj);
printf("str %s null.\n\0", str == 0 ? "is" : "is not");
delete list;
delete obj;
}

Example.cpp: In function 'int main(int, char**)':
Example.cpp:39: error: cannot convert from base 'IObject' to derived
type 'String' via virtual base 'IObject'
Frankly, this isn't Java. I would dump the Object class and keep things
by value when possible. But then I would use std::string instead of
inventing my own string class...

--
To send me email, put "sheltie" in the subject.
Oct 29 '06 #2

Standard answer to dynamic cast ... If you have to use it, you're
almost certainly doing somthing wrong - that said, let's move on.

mijobee wrote:
Hello Everyone,

I just wanted to check that I'm using dynamic_cast correctly. I have a
hierarchy of objects using pure virtual classes and virtual inheritance
to implement interfaces. I ran into a problem using C-style casting to
an instance of a derived class from its interface type to a variable of
its concrete type. I was confused because I thought C-style casts
always compiled even if they wouldn't run correctly at runtime. I
modified the code to use dynamic_cast which seems correct, compiles and
runs but have found some contradictory information about its use so I
wanted to confirm I'm using it correctly. The code below illustrates
my problem. Thanks for your help.
#include <stdio.h>

class IObject
{
public:
virtual bool Equals(IObject *object) = 0;

};

class IList : public virtual IObject
{
public:
virtual IObject *Get(int index) = 0;
};

class Object : public virtual IObject
{
public:
virtual bool Equals(IObject *object) {
return this == object;
}
};

class ArrayList : public Object, public virtual IList
{
public:
virtual IObject *Get(int index) {
return this; // Just return something
}
};

class String : public Object { };
int main(int argc, char *argv[])
{
IList *list = new ArrayList();
IObject *obj = new String();
String *str = (String *)obj;
// This works: String *str = dynamic_cast<String *>(obj);
printf("str %s null.\n\0", str == 0 ? "is" : "is not");

}

Example.cpp: In function 'int main(int, char**)':
Example.cpp:39: error: cannot convert from base 'IObject' to derived
type 'String' via virtual base 'IObject'
I don't in particular understand why the C style cast fails, but it is a
good thing IMHO because it's time to give up on it. It's too error
prone. If I were you I would look at the compiler docs to see if the
compiler has a flag to permit such things.
String *str = dynamic_cast<String *>(obj);

if ( str != 0 )
{
// obj IS a pointer to String
// go ahead an use str
} else {
// obj IS NOT at pointer to String
// so other thing
}
Oct 29 '06 #3
Gianni Mariani wrote:
Standard answer to dynamic cast ... If you have to use it, you're
almost certainly doing somthing wrong - that said, let's move on.
True, but with one notable exception that is relevant to the original
question.

A dynamic_cast should always be used when casting from a derived class
to a virtual base. Using a static_cast (which is always a safe
operation when casting from a derived class to a non-virtual base)
leads to undefined behavior when casting to a virtual base class.

Greg

Oct 29 '06 #4
Greg wrote:
Gianni Mariani wrote:
>Standard answer to dynamic cast ... If you have to use it, you're
almost certainly doing somthing wrong - that said, let's move on.

True, but with one notable exception that is relevant to the original
question.

A dynamic_cast should always be used when casting from a derived class
to a virtual base. Using a static_cast (which is always a safe
operation when casting from a derived class to a non-virtual base)
leads to undefined behavior when casting to a virtual base class.
C and V please. If I understand you:

struct A {};
struct B : virtual A {}

int main()
{
B *b = new B;
/* You claim that this is undefined behavior? */
A * a = static_cast<A*>(b)
}

I haven't found anything that would suggest that.

--
Clark S. Cox III
cl*******@gmail.com
Oct 29 '06 #5

Clark S. Cox III wrote:
Greg wrote:
Gianni Mariani wrote:
Standard answer to dynamic cast ... If you have to use it, you're
almost certainly doing somthing wrong - that said, let's move on.
True, but with one notable exception that is relevant to the original
question.

A dynamic_cast should always be used when casting from a derived class
to a virtual base. Using a static_cast (which is always a safe
operation when casting from a derived class to a non-virtual base)
leads to undefined behavior when casting to a virtual base class.

C and V please. If I understand you:

struct A {};
struct B : virtual A {}

int main()
{
B *b = new B;
/* You claim that this is undefined behavior? */
A * a = static_cast<A*>(b)
}

I haven't found anything that would suggest that.
Actually, I had the direction of the cast reversed. The corrected
example would be::

struct A {};
struct B : virtual A {}

int main()
{
A *a = new B;

B * b = static_cast<B*>(a); // undefined
}

If A were an ordinary base class of B then the static_cast would be OK.

Greg

Oct 29 '06 #6

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

Similar topics

18
by: Andreas Sch. | last post by:
Hello, I had been quite suprised by the following little program: ---- cut ---- #include "iostream.h" class base {
17
by: steve | last post by:
I am writing for game application. Performance is an issue. Any advise would be appreiciated.
4
by: Maurice Termeer | last post by:
Hi, suppose i've got this: class a { public: int n; }; class b : public a { public: };
2
by: hijinks | last post by:
I am trying to port a python program into c++ to more learn about c++... so i am trying to do a MVC design.. so here is my events class Event { public: Event() {} Event(string text) {...
5
by: Leslaw Bieniasz | last post by:
Hello, I have the following OOP design problem. I have a base class designed as an element of a list, let's say: class A { public: // some stuff
22
by: Boris | last post by:
I'm porting code from Windows to UNIX and ran into a problem with dynamic_cast. Imagine a class hierarchy with three levels: class Level2 derives from Level1 which derives from Base. If you look...
15
by: Grizlyk | last post by:
Hello. Returning to question of manual class type identification, tell me, for ordinary inheritance is C++ garantee that dynamic_cast<Derived*>(Base*) can be implemented similarly to ...
25
by: lovecreatesbea... | last post by:
Suppose I have the following three classes, GrandBase <-- Base <-- Child <-- GrandChild The following cast expression holds true only if pBase points object of type of ``Child'' or...
18
by: Eric | last post by:
Ok...this seems to be treading into some really esoteric areas of c++. I will do my best to explain this issue, but I don't fully understand what is happening myself. I am hoping that the problem...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
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
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
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
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
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...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

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.