473,473 Members | 1,730 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

static_cast and virtual base classes

Is it safe to use static_cast to downcast from a virtual base class?

For example,

class V {};
class A: public virtual V {};
class B: public virtual V {};
class C: public A, public B;

void fn(V& v)
{
A& a = static_cast<A&>(v);
B& b = static_cast<B&>(v);
C& c = static_cast<C&>(v);
}

Assuming that the parameter to fn() is an instance of C, of course.

Or do I have to use dynamic_cast? When is static_cast not sufficient?

-dr
May 24 '06 #1
6 4641
Dave Rahardja wrote:
Is it safe to use static_cast to downcast from a virtual base class?
What do you mean by "safe"? As in "nobody is going to get killed"?
For example,

class V {};
class A: public virtual V {};
class B: public virtual V {};
class C: public A, public B;

void fn(V& v)
{
A& a = static_cast<A&>(v);
B& b = static_cast<B&>(v);
C& c = static_cast<C&>(v);
}

Assuming that the parameter to fn() is an instance of C, of course.

Or do I have to use dynamic_cast? When is static_cast not sufficient?


'static_cast' is sufficient when your compiler says it's sufficient. Trust
your compiler, it knows (in most cases).

BTW, you can't use 'dynamic_cast' here, your classes are not polymorphic.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
May 24 '06 #2
On Wed, 24 May 2006 09:06:41 -0400, "Victor Bazarov" <v.********@comAcast.net>
wrote:
Dave Rahardja wrote:
Is it safe to use static_cast to downcast from a virtual base class?
What do you mean by "safe"? As in "nobody is going to get killed"?


By "safe" I mean "yield defined behavior".
For example,

class V {};
class A: public virtual V {};
class B: public virtual V {};
class C: public A, public B;

void fn(V& v)
{
A& a = static_cast<A&>(v);
B& b = static_cast<B&>(v);
C& c = static_cast<C&>(v);
}

Assuming that the parameter to fn() is an instance of C, of course.

Or do I have to use dynamic_cast? When is static_cast not sufficient?


'static_cast' is sufficient when your compiler says it's sufficient. Trust
your compiler, it knows (in most cases).

BTW, you can't use 'dynamic_cast' here, your classes are not polymorphic.


D'oh, my bad. Yes, assume there are pure virtual functions in V that A, B, and
C are providing.

-dr
May 24 '06 #3
Dave Rahardja wrote:
Is it safe to use static_cast to downcast from a virtual base class?

For example,

class V {};
class A: public virtual V {};
class B: public virtual V {};
class C: public A, public B;

void fn(V& v)
{
A& a = static_cast<A&>(v);
B& b = static_cast<B&>(v);
C& c = static_cast<C&>(v);
}

Assuming that the parameter to fn() is an instance of C, of course.

Or do I have to use dynamic_cast? When is static_cast not sufficient?


You must a dynamic_cast when casting from a virtual base class to a
derived class (or the other way around). Using a static_cast for such a
conversion would lead to undefined behavior.

Greg

May 24 '06 #4

Greg wrote:
You must a dynamic_cast when casting from a virtual base class to a
derived class (or the other way around). Using a static_cast for such a
conversion would lead to undefined behavior.


I don't believe that is accurate; if so please provide the clause
because there are many, many expert written books that show how to
write a safe and fast "polymorphic_cast" by performing a dynamic cast
and testing the result when in debug build but static cast otherwise.

May 24 '06 #5
Noah Roberts wrote:
Greg wrote:
You must a dynamic_cast when casting from a virtual base class to a
derived class (or the other way around). Using a static_cast for such a
conversion would lead to undefined behavior.


I don't believe that is accurate; if so please provide the clause


"An lvalue of type "cv1 B", where B is a class type, can be cast to
type "reference to cv2 D", where D is a class derived (clause 10)
from B, if a valid standard conversion from "pointer to D" to
"pointer to B" exists (4.10), cv2 is the same cv-qualification as,
or greater cv-qualification than, cv1, and B is not a virtual base
class of D. The result is an lvalue of type "cv2 D." If the lvalue
of type "cv1 B" is actually a sub-object of an object of type D,
the lvalue refers to the enclosing object of type D. Otherwise, the
result of the cast is undefined." (5.2.9§5)
Jonathan

May 24 '06 #6
Noah Roberts wrote:
Greg wrote:
You must a dynamic_cast when casting from a virtual base class to a
derived class (or the other way around). Using a static_cast for such a
conversion would lead to undefined behavior.


I don't believe that is accurate; if so please provide the clause
because there are many, many expert written books that show how to
write a safe and fast "polymorphic_cast" by performing a dynamic cast
and testing the result when in debug build but static cast otherwise.


A dynamic_cast can indeed be safely replaced with a static_cast to
convert from a derived to a base class - just as long as there is no
virtual inheritance involved. And given how rare virtual base classes
are in practice - it is not surprising that the fact that a
dynamic_cast is required in this case - rarely comes up.

The relevant clauses are §5.2.9/2 and §5.2.9/9 of which I quote the
first one here:

"An lvalue of type cv1 B, where B is a class type, can be cast to type
"reference to cv2 D", where D is a class derived (clause 10) from B, if
a valid standard conversion from "pointer to D" to "pointer to B"
exists (4.10), cv2 is the same cv-qualification as, or greater
cv-qualification than, cv1, and B is not a virtual base class of D.
....Otherwise, the result of the cast is undefined."

Note the qualification: "B is not a virtual base class of D".

Greg

May 24 '06 #7

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

Similar topics

7
by: buds | last post by:
Hi all, Following is the assigment operator of a derived class Derived& Derived::operator=(const Derived& inDerived) { //to assign to the base class object the following statement ...
4
by: Wenjie | last post by:
Hello, I have a class B to mediate/isolate between implementation and their users (like used in an abstract factory class pattern): // B.h class B { static B* getImpl(); static void...
62
by: christopher diggins | last post by:
Since nobody responded to my earlier post , I thought I would try to explain what I am doing a bit differently. When multiply inheriting pure virtual (abstract) base classes, a class obviously...
26
by: Steven T. Hatton | last post by:
The code shown below is an example from the Coin3D documentation. I believe the use of the C-style cast is safe under the circumstances, but from what I've been exposed to (TC++PL(SE)), I would...
13
by: GianGuz | last post by:
Everyone knows about the complex and cpu-expensive procedures taken by dynamic_cast to find the right function call in a virtual classes hierarchy. The question I would to rise is when...
2
by: Amit | last post by:
Greetings. I am having some problem while using a cast operation(static_cast and/or dynamic_cast) between base and derived objects when passing to functions. what I have is something like this.. ...
14
by: JPRoot | last post by:
Hi I use the following syntax to have events inherited from base to child classes which works nicely (virtual and override keyword on events). But I am wondering if it is a "supported" way of using...
2
by: Lucy Ludmiller | last post by:
I have two classes: class base { ... }; and class derived : public base { ... }; I have a function :
2
by: Heinz Ketchup | last post by:
Hello, I'm looking to bounce ideas off of anyone, since mainly the idea of using Multiple Virtual Inheritance seems rather nutty. I chalk it up to my lack of C++ Experience. Here is my...
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
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
1
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...
0
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...
1
muto222
php
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

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.