Hello,
I had been quite suprised by the
following little program:
---- cut ----
#include "iostream.h"
class base {
**public:
**base(){}
**virtual*~base(){};
**void*printType(base***obj);
};
class derived : public base {
**public:
**virtual*void*doIt()
**{
****printType(this);
**}**
};
void base::printType(base * obj) {
**cout*<<*"type*is*"*<<*typeid(obj).name()*<<*endl ;
**cout*<<*dynamic_cast<derived**>(obj)*<<*endl;
}
int main(int argc, char * argv[]) {
**derived*myObj;
**myObj.doIt();
}
---- cut ----
It prints:
type is P4base
0xbfffec00
My expectation was to see "derived" for
the type name.
And even if it is identified as "base"
the RTTI should not be able to dynamic-cast
it to a derived object which it is reported
not to be.
Tested with gcc 3.3 and 3.3.2.
Somebody able to enlighten me?
Greetings,
Andreas 18 2796
Andreas Sch. wrote: Hello,
I had been quite suprised by the following little program:
---- cut ----
#include "iostream.h"
class base { public: base(){} virtual ~base(){}; void printType(base * obj); };
class derived : public base { public: virtual void doIt() { printType(this); } };
void base::printType(base * obj) { cout << "type is " << typeid(obj).name() << endl;
This isn't a virtual function, so it will be called with type of 'this'
set to "base", even though it was called from a virtual function
(virtual-ness doesn't pass along the calling sequence, its on a
per-function basis.) Dynamic-casting
cout << dynamic_cast<derived *>(obj) << endl;
I don't see the purpose of doing this: it just prints out the pointer
value. Did you forget to typeid() it?
}
int main(int argc, char * argv[]) { derived myObj; myObj.doIt(); }
---- cut ----
-- http://www.it-is-truth.org/
Andreas Sch. wrote: Hello,
I had been quite suprised by the following little program:
---- cut ----
#include "iostream.h"
this header is not standard - use #include <iostream> class base { public: base(){} virtual ~base(){};
^^^^^^^^ ';' not needed
void printType(base * obj); };
class derived : public base { public: virtual void doIt() { printType(this); } };
void base::printType(base * obj) { cout << "type is " << typeid(obj).name() << endl;
^^^^^^^^^^^^^^^ ... this is the same as
cout << "type is " << typeid( (base *) 0 ).name() << endl;
cout << dynamic_cast<derived *>(obj) << endl; }
int main(int argc, char * argv[]) { derived myObj; myObj.doIt(); }
---- cut ----
It prints:
type is P4base 0xbfffec00
My expectation was to see "derived" for the type name.
And even if it is identified as "base" the RTTI should not be able to dynamic-cast it to a derived object which it is reported not to be.
Tested with gcc 3.3 and 3.3.2.
Somebody able to enlighten me?
Try this:
class derived;
#include <iostream>
using namespace std;
class base {
public:
base(){}
virtual ~base(){}
template <typename T>
void printType(T * obj)
{
cout << "type is " << typeid(obj).name() << endl;
cout << dynamic_cast<derived *>(obj) << endl;
}
};
class derived : public base {
public:
virtual void doIt()
{
printType(this);
}
};
int main(int argc, char * argv[]) {
derived myObj;
myObj.doIt();
}
Asfand Yar Qazi wrote: (...) void base::printType(base * obj) { cout << "type is " << typeid(obj).name() << endl; This isn't a virtual function, so it will be called with type of 'this' set to "base", even though it was called from a virtual function (virtual-ness doesn't pass along the calling sequence, its on a per-function basis.) Dynamic-casting
Lets see if I got it: typeid does not evaluate the
type information in memory but depends on the type
of the "obj" pointer (and not on what it is pointing to). cout << dynamic_cast<derived *>(obj) << endl;
I don't see the purpose of doing this: it just prints out the pointer value. Did you forget to typeid() it?
I just wanted to see if the dynamic_cast fails and
delivers 0x0. I expected it to fail since the typeid-line
printed "base" and not "derived".
Thanks for your answer!
Andreas
Gianni Mariani wrote: (...) #include "iostream.h" this header is not standard - use #include <iostream>
Ok... class base { (...) virtual ~base(){};
^^^^^^^^ ';' not needed
Oops, sure. (...) void base::printType(base * obj) { cout << "type is " << typeid(obj).name() << endl;
^^^^^^^^^^^^^^^ ... this is the same as
cout << "type is " << typeid( (base *) 0 ).name() << endl;
So typeid delivers the type of the pointer,
not the object.
(...) Try this: (...)
That worked. Thank you.
I have been hunting a strange problem in a program
which fails at a dynamic_cast. To debug that situation
I heavily used typeid() and was quite suprised about
its different behavior.
If I am able to shorten the program to a small
example and still produce the same behavior I'll
write that here, too.
Greetings,
Andreas
"Andreas Sch." <no******@yahoo.com> wrote in message
news:bu************@ID-152588.news.uni-berlin.de... Asfand Yar Qazi wrote: (...) void base::printType(base * obj) { cout << "type is " << typeid(obj).name() << endl;
This isn't a virtual function, so it will be called with type of 'this' set to "base", even though it was called from a virtual function (virtual-ness doesn't pass along the calling sequence, its on a per-function basis.) Dynamic-casting
Lets see if I got it: typeid does not evaluate the type information in memory but depends on the type of the "obj" pointer (and not on what it is pointing to).
This is a quote from msdn -
<Quote>
If the expression points to a base class type, yet the object is actually of a
type derived from that base class, a type_info reference for the derived class
is the result. The expression must point to a polymorphic type (a class with
virtual functions). Otherwise, the result is the type_info for the static class
referred to in the expression. Further, the pointer must be dereferenced so that
the object it points to is used. Without dereferencing the pointer, the result
will be the type_info for the pointer, not what it points to.
</Quote>
Best wishes,
Sharad
Disclaimer : I know msdn isn't totally accurate at places but not here ;-)
"Sharad Kala" <no*****************@yahoo.com> wrote in message
news:bu************@ID-221354.news.uni-berlin.de...
</snip>
You don't seem to include typeinfo in your code.
Quote from Section 5.2.8.6 of the standard.
" If the header <typeinfo> is not included prior to a use of typeid, the program
is ill-formed. "
Best wishes,
Sharad
Andreas Sch. wrote: void base::printType(base * obj) { cout << "type is " << typeid(obj).name() << endl;
^^^^^^^^^^^^^^^ ... this is the same as
cout << "type is " << typeid( (base *) 0 ).name() << endl;
So typeid delivers the type of the pointer, not the object.
Yes. That's what you asked for. If you provide a pointer to typeid(), it
will tell you that it's a pointer ;-)
If you want info about what the pointer points to, you need to
dereference, i.e typeid(*obj).
Hi!
First of all, thank you all for your valuable
answers to my previous question!
Again, I have a short program illustrating my
(next) problem:
--- snipp ---
#include <typeinfo>
#include <iostream>
class Base
{
public:
Base(){};
virtual ~Base(){};
void calledMethod( Base * a_Base );
};
class Derived : Base
{
public:
Derived() : Base(){};
virtual ~Derived(){};
virtual void callingMethod();
};
void Base::calledMethod( Base * a_base )
{
std::cout << "Parameter is of type \"" << typeid(*a_base).name()
<< "\" at address " << dynamic_cast<Derived *>(a_base)
<< std::endl;
}
void Derived::callingMethod( )
{
std::cout << "I am of type \"" << typeid(*this).name()
<< "\" at address " << dynamic_cast<Derived *>(this)
<< std::endl;
calledMethod( this );
}
int main(int argc, char * argv[])
{
Derived myDerived;
myDerived.callingMethod();
}
/* Program output:
I am of type "7Derived" at address 0xbfffea90
Parameter is of type "7Derived" at address 0
*/
--- snipp ---
The question is: Why is the dynamic_cast in calledMethod()
failing?
RU,
Andreas
"Andreas Sch." <no******@yahoo.com> wrote in message news:bv************@ID-152588.news.uni-berlin.de... class Derived : Base
You want
class Derived : public Base
I can't even understand why this compiles.
Ron Natalie wrote: class Derived : Base
You want class Derived : public Base
I can't even understand why this compiles.
I don't know whether it should compile or not, but this probably is the
reason why it doesn't work. If you derive virtually, Base is not an
accessible base class of Derived.
"Rolf Magnus" <ra******@t-online.de> wrote in message news:bv*************@news.t-online.com... Ron Natalie wrote:
class Derived : Base
You want class Derived : public Base
I can't even understand why this compiles.
I don't know whether it should compile or not, but this probably is the reason why it doesn't work. If you derive virtually, Base is not an accessible base class of Derived.
You mean privately, not virtually.
The program is ill-formed because you can't call the base class "calledMethod"
function since it's not accessible.
Ron Natalie wrote: "Rolf Magnus" <ra******@t-online.de> wrote in message news:bv*************@news.t-online.com...
Ron Natalie wrote:
class Derived : Base
You want class Derived : public Base
I can't even understand why this compiles.
I don't know whether it should compile or not, but this probably is the reason why it doesn't work. If you derive virtually, Base is not an accessible base class of Derived.
You mean privately, not virtually.
The program is ill-formed because you can't call the base class "calledMethod" function since it's not accessible.
It is not ill-formed, to quote 11.2.1 from the standard:
"...If a class is declared to be a base class for another class using
the private access specifier, the public and protected members of the
base class are accessible as private members of the derived class."
Therefore the following code is legal:
class A {
public:
void A_f ( ) { }
};
class B : A {
public:
void f ( ) { A_f ( ); }
};
Michael Mellor
Ron Natalie wrote: "Rolf Magnus" <ra******@t-online.de> wrote in message news:bv*************@news.t-online.com... Ron Natalie wrote:
>> class Derived : Base > > You want > class Derived : public Base > > I can't even understand why this compiles. I don't know whether it should compile or not, but this probably is the reason why it doesn't work. If you derive virtually, Base is not an accessible base class of Derived. You mean privately, not virtually.
Of course. Sorry.
The program is ill-formed because you can't call the base class "calledMethod" function since it's not accessible.
calledMethod is only called by Derived::callingMethod, from where it is
accessible.
"Rolf Magnus" <ra******@t-online.de> wrote in message news:bv*************@news.t-online.com... calledMethod is only called by Derived::callingMethod, from where it is accessible.
It is NOT accessible. Base is inherited privately. NONE of it's members
are accessible.
Ron Natalie wrote: "Rolf Magnus" <ra******@t-online.de> wrote in message news:bv*************@news.t-online.com...
calledMethod is only called by Derived::callingMethod, from where it is accessible.
It is NOT accessible. Base is inherited privately. NONE of it's members are accessible.
The derived class can access the base class's public methods or else how
would private inheritence ever be useful?
Michael Mellor
Ron Natalie wrote: "Rolf Magnus" <ra******@t-online.de> wrote in message news:bv*************@news.t-online.com... calledMethod is only called by Derived::callingMethod, from where it is accessible.
It is NOT accessible. Base is inherited privately. NONE of it's members are accessible.
....from the "outside world". But from Derived they are. If you derive
privately, public and protected members of Base are private in Derived,
and so they can be called from Derived's member functions. If that
weren't the case, deriving privatly would just be another way of not
deriving at all. Only members that are private in Base are not
accessible to Derived, since private members can only be accessed by
the class itself and to friends.
Ron Natalie schrieb: "Rolf Magnus" <ra******@t-online.de> wrote (...): Ron Natalie wrote:
>> class Derived : Base > > You want > class Derived : public Base > (...) I don't know whether it should compile or not, but this probably is the reason why it doesn't work. If you derive virtually, Base is not an accessible base class of Derived. You mean privately, not virtually. (...)
I tried using public here and yes, it works
as desired.
When deriving privately the outside world should have
problems accessing the base class' members but what
about having a reference to the object?
I may always have a reference to an object which has
only private members (attributes and methods).
In this example the base class tries to cast
a pointer so that it points to a derived object.
Why is this failing?
In other words, I see the effect of deriving public
and know that it should hide the base class members
from being accessed from outside but why does this
affect the dynamic cast?
Greetings,
Andreas
Andreas Schallenberg wrote: In this example the base class tries to cast a pointer so that it points to a derived object. Why is this failing?
dynamic_cast will only succeed if the pointed base class object is
inherited via public inheritance otherwise it fails (C++ std 5.2.7/8).
In such a case use static_cast or C style cast.
Regards,
Janusz This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: Jamie Burns |
last post by:
Hello,
I just did a simple benchmark:
for (xx=0;xx<100000;xx++) {
rDerived* derived = dynamic_cast<rDerived*>(object);
if (derived) derived->setValue(message.data.messageSetInt.value);
}
...
|
by: Marco Jez |
last post by:
Hi everyone!
I would like to use the reference returned by typeid as key in a std::map.
Is it safe to assume that typeid(T) (where T is a type name) will always
return the same reference to the...
|
by: Adam Zimny |
last post by:
This is fragment of code from Bruce Eckel's Thinking in c++ ( last 3 couts
are mine to show what happened ). The question is: is Bruce Eckel wrong or
g++ ( my version is 3.2.3 ) is buggy ?
//:...
|
by: mscava |
last post by:
Here are my classes. Each of them has virtual destructor:
class Object { ... };
class Door : public Object { ... };
class ClosedDoor : public Door { ... };
class OpenedDoor : public Door { ......
|
by: taylorcarr |
last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
|
by: Charles Arthur |
last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
|
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$) {
}
...
|
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...
|
by: nemocccc |
last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
|
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...
|
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,...
|
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: 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,...
| | |