473,386 Members | 1,962 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,386 software developers and data experts.

why dynamic_cast fail here?

In the example below, why does the dynamic_cast fail (return NULL)? It
should be able to cast between sibling classes ...
#include <iostream>

class A
{
public:
virtual const int get() const = 0;
};

class B : public A
{
public:
virtual const int get() const { return 0; }
};

class C : public A
{
public:
virtual const int get() const { return 1; }
};

int main()
{
A *a;

a = new B();
std::cout << a->get() << std::endl;

a = dynamic_cast<C*>(a);
if(a)
std::cout << a->get() << std::endl;

return 0;
}

Mar 15 '07 #1
8 5405
pi*******@gmail.com wrote:
In the example below, why does the dynamic_cast fail (return NULL)?
Because a B is not a C.
It should be able to cast between sibling classes ...
No, it shouldn't. An instance of class B only provides the A interface and
the B interface. So why would you want to access it through the C
interface? What would you expect to happen if C had another member function
and you'd try to call that on your B?
#include <iostream>

class A
{
public:
virtual const int get() const = 0;
};

class B : public A
{
public:
virtual const int get() const { return 0; }
};

class C : public A
{
public:
virtual const int get() const { return 1; }
};

int main()
{
A *a;

a = new B();
std::cout << a->get() << std::endl;

a = dynamic_cast<C*>(a);
if(a)
std::cout << a->get() << std::endl;

return 0;
}
Mar 15 '07 #2
On Mar 15, 12:12 pm, Rolf Magnus <ramag...@t-online.dewrote:
pietro...@gmail.com wrote:
In the example below, why does the dynamic_cast fail (return NULL)?

Because a B is not a C.
It should be able to cast between sibling classes ...

No, it shouldn't. An instance of class B only provides the A interface and
the B interface. So why would you want to access it through the C
interface? What would you expect to happen if C had another member function
and you'd try to call that on your B?
#include <iostream>
class A
{
public:
virtual const int get() const = 0;
};
class B : public A
{
public:
virtual const int get() const { return 0; }
};
class C : public A
{
public:
virtual const int get() const { return 1; }
};
int main()
{
A *a;
a = new B();
std::cout << a->get() << std::endl;
a = dynamic_cast<C*>(a);
if(a)
std::cout << a->get() << std::endl;
return 0;
}
Yes, I see how that could case problems. So does that mean that the
following is not true (http://www.acm.org/crossroads/xrds3-1/
ovp3-1.html):

"The dynamic_cast Operator

The dynamic_cast operator takes the form

dynamic_cast<T(expr)

and can be used only for pointer or reference types to navigate a
class hierarchy. The dynamic_cast operator can be used to cast from a
derived class pointer to a base class pointer, cast a derived class
pointer to another derived (sibling) class pointer, or cast a base
class pointer to a derived class pointer. Each of these conversions
may also be applied to references. In addition, any pointer may also
be cast to a void*."

Or else, what are the conditions for casting between sibling classes?

Mar 15 '07 #3
pi*******@gmail.com wrote:
On Mar 15, 12:12 pm, Rolf Magnus <ramag...@t-online.dewrote:
>pietro...@gmail.com wrote:
In the example below, why does the dynamic_cast fail (return NULL)?

Because a B is not a C.
It should be able to cast between sibling classes ...

No, it shouldn't. An instance of class B only provides the A interface
and the B interface. So why would you want to access it through the C
interface? What would you expect to happen if C had another member
function and you'd try to call that on your B?
#include <iostream>
class A
{
public:
virtual const int get() const = 0;
};
class B : public A
{
public:
virtual const int get() const { return 0; }
};
class C : public A
{
public:
virtual const int get() const { return 1; }
};
int main()
{
A *a;
a = new B();
std::cout << a->get() << std::endl;
a = dynamic_cast<C*>(a);
if(a)
std::cout << a->get() << std::endl;
return 0;
}

Yes, I see how that could case problems. So does that mean that the
following is not true (http://www.acm.org/crossroads/xrds3-1/
ovp3-1.html):

"The dynamic_cast Operator

The dynamic_cast operator takes the form

dynamic_cast<T(expr)

and can be used only for pointer or reference types to navigate a
class hierarchy. The dynamic_cast operator can be used to cast from a
derived class pointer to a base class pointer, cast a derived class
pointer to another derived (sibling) class pointer, or cast a base
class pointer to a derived class pointer. Each of these conversions
may also be applied to references. In addition, any pointer may also
be cast to a void*."

Or else, what are the conditions for casting between sibling classes?
I think it means just that those are the cases where you may use a
dynamic_cast. It might fail (returning a null pointer or throwing an
exception), but you're allowed to use it.
And there is also multiple inheritance:

class A
{
public:
virtual ~A() {}
};

class B
{
public:
virtual ~B() {}
};

class C: public A, public B
{
};

int main()
{
A* a = new C;
B* b = dynamic_cast<B*>(a); // shoulnd't fail
delete b;
}

Mar 15 '07 #4
On Mar 15, 12:37 pm, Rolf Magnus <ramag...@t-online.dewrote:
pietro...@gmail.com wrote:
On Mar 15, 12:12 pm, Rolf Magnus <ramag...@t-online.dewrote:
pietro...@gmail.com wrote:
In the example below, why does the dynamic_cast fail (return NULL)?
Because a B is not a C.
It should be able to cast between sibling classes ...
No, it shouldn't. An instance of class B only provides the A interface
and the B interface. So why would you want to access it through the C
interface? What would you expect to happen if C had another member
function and you'd try to call that on your B?
#include <iostream>
class A
{
public:
virtual const int get() const = 0;
};
class B : public A
{
public:
virtual const int get() const { return 0; }
};
class C : public A
{
public:
virtual const int get() const { return 1; }
};
int main()
{
A *a;
a = new B();
std::cout << a->get() << std::endl;
a = dynamic_cast<C*>(a);
if(a)
std::cout << a->get() << std::endl;
return 0;
}
Yes, I see how that could case problems. So does that mean that the
following is not true (http://www.acm.org/crossroads/xrds3-1/
ovp3-1.html):
"The dynamic_cast Operator
The dynamic_cast operator takes the form
dynamic_cast<T>(expr)
and can be used only for pointer or reference types to navigate a
class hierarchy. The dynamic_cast operator can be used to cast from a
derived class pointer to a base class pointer, cast a derived class
pointer to another derived (sibling) class pointer, or cast a base
class pointer to a derived class pointer. Each of these conversions
may also be applied to references. In addition, any pointer may also
be cast to a void*."
Or else, what are the conditions for casting between sibling classes?

I think it means just that those are the cases where you may use a
dynamic_cast. It might fail (returning a null pointer or throwing an
exception), but you're allowed to use it.
And there is also multiple inheritance:

class A
{
public:
virtual ~A() {}

};

class B
{
public:
virtual ~B() {}

};

class C: public A, public B
{

};

int main()
{
A* a = new C;
B* b = dynamic_cast<B*>(a); // shoulnd't fail
delete b;

}
Okay, thanks for the quick help.

Mar 15 '07 #5
pi*******@gmail.com wrote:
On Mar 15, 12:12 pm, Rolf Magnus <ramag...@t-online.dewrote:
>pietro...@gmail.com wrote:
In the example below, why does the dynamic_cast fail (return NULL)?

Because a B is not a C.
It should be able to cast between sibling classes ...

No, it shouldn't. An instance of class B only provides the A interface
and the B interface. So why would you want to access it through the C
interface? What would you expect to happen if C had another member
function and you'd try to call that on your B?
#include <iostream>
class A
{
public:
virtual const int get() const = 0;
};
class B : public A
{
public:
virtual const int get() const { return 0; }
};
class C : public A
{
public:
virtual const int get() const { return 1; }
};
int main()
{
A *a;
a = new B();
std::cout << a->get() << std::endl;
a = dynamic_cast<C*>(a);
if(a)
std::cout << a->get() << std::endl;
return 0;
}

Yes, I see how that could case problems. So does that mean that the
following is not true (http://www.acm.org/crossroads/xrds3-1/
ovp3-1.html):

"The dynamic_cast Operator

The dynamic_cast operator takes the form

dynamic_cast<T(expr)

and can be used only for pointer or reference types to navigate a
class hierarchy. The dynamic_cast operator can be used to cast from a
derived class pointer to a base class pointer, cast a derived class
pointer to another derived (sibling) class pointer, or cast a base
class pointer to a derived class pointer. Each of these conversions
may also be applied to references. In addition, any pointer may also
be cast to a void*."

Or else, what are the conditions for casting between sibling classes?
I think it means just that those are the cases where you may use a
dynamic_cast. It might fail (returning a null pointer or throwing an
exception), but you're allowed to use it.
And there is also multiple inheritance:

class Base
{
public:
virtual ~Base() {}
};

class A : public Base
{
};

class B : public Base
{
};

class C: public A, public B
{
};

int main()
{
A* a = new C;
B* b = dynamic_cast<B*>(a); // shoulnd't fail
delete b;
}

Mar 15 '07 #6
pi*******@gmail.com wrote:
In the example below, why does the dynamic_cast fail (return NULL)? It
should be able to cast between sibling classes ...
No, it should not and is not. See [5.2.7] for the conversions supported by
dynamic_cast<>. Specifically [5.2.7/8]

The run-time check logically executes as follows:
? If, in the most derived object pointed (referred) to by v, v points
(refers) to a public base class subobject of a T object, and if only one
object of type T is derived from the sub-object pointed (referred) to by
v, the result is a pointer (an lvalue referring) to that T object.
? Otherwise, if v points (refers) to a public base class sub-object of the
most derived object, and the type of the most derived object has a base
class, of type T, that is unambiguous and public, the result is a
pointer (an lvalue referring) to the T sub-object of the most derived
object.
? Otherwise, the run-time check fails.

#include <iostream>

class A
{
public:
virtual const int get() const = 0;
};

class B : public A
{
public:
virtual const int get() const { return 0; }
};

class C : public A
{
public:
virtual const int get() const { return 1; }
};

int main()
{
A *a;

a = new B();
std::cout << a->get() << std::endl;

a = dynamic_cast<C*>(a);
The dynamic type of *a is B. The dynamic_cast<is specifically designed to
catch the error in trying to regard this object as anything that it not
truly is. Therefore, dynamic_cast<will fail if you cast the object to any
type that is not a base class of its dynamic type.

if(a)
std::cout << a->get() << std::endl;

return 0;
}

Best

Kai-Uwe Bux
Mar 15 '07 #7
pi*******@gmail.com wrote:
Okay, thanks for the quick help.
Damn, I wrote a supersede for my posting in the hope that it hadn't already
spread to too many usenet servers, but you were too quick :-)
I guess you didn't notice that in my example, the two classes aren't
actually siblings. See my other posting for a better example.

Mar 15 '07 #8
On Mar 15, 8:51 pm, pietro...@gmail.com wrote:
In the example below, why does the dynamic_cast fail (return NULL)? It
should be able to cast between sibling classes ...

#include <iostream>

class A
{
public:
virtual const int get() const = 0;

};

class B : public A
{
public:
virtual const int get() const { return 0; }

};

class C : public A
{
public:
virtual const int get() const { return 1; }

};

int main()
{
A *a;

a = new B();
std::cout << a->get() << std::endl;

a = dynamic_cast<C*>(a);
if(a)
std::cout << a->get() << std::endl;

return 0;}
a points an object which is type of B and you are trying to convert it
to C* it should not work.

Mar 15 '07 #9

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

Similar topics

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...
8
by: Thomas Lorenz | last post by:
Hello, first, I didn't find any reference to my question through googling. dynamic_cast uses RTTI to determine if the cast expression is valid. Invalid casts of pointers give a '0'-result. As...
3
by: Axter | last post by:
I'm wondering about the practical use of dynamic_cast in reusable or generic code. I'm currently working on a smart pointer that can be used on vector and other STL containers. See following...
5
by: tthunder | last post by:
Hi @all, Perhaps some of you know my problem, but I had to start a new thread. The old one started to become very very confusing. Here clean code (which compiles well with my BCB 6.0 compiler)....
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: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
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
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
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
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...

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.