 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
cman Guest
|
Posted: Fri Feb 20, 2004 8:53 pm Post subject: typecasting the base class to derived class. |
|
|
#include <stdio.h>
class Base
{
public:
Base()
{
printf("Base()n");
}
~Base()
{
printf("~Base()n");
}
};
class Derived:public Base
{
public:
Derived()
{
printf("Derived()n");
}
void myConst() const
{
printf("Derived's myConst function x=%d",x);
}
~Derived()
{
printf("~Derived()n");
}
int x;
};
main()
{
Derived *dptr;
dptr=(Derived *)new Base();
dptr->x=10;
dptr->myConst();
delete dptr;
}
In the above code "dptr->myConst()" succeeds without giving any error
on Solaris, but generates an exception when ran on Winodws after
compiling in VC++
My Question is Why does it not fail? since typecasting should not
define x... this call should fail. I replaced "x" with "x[1024]" and
then used the last element in the array above, to isolate the
possiblity of having a fluke. But it still worked !
Thanks.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Thomas Tutone Guest
|
Posted: Sat Feb 21, 2004 10:49 am Post subject: Re: typecasting the base class to derived class. |
|
|
"cman" <complangman (AT) yahoo (DOT) com> wrote:
| Quote: | #include <stdio.h
class Base
{
public:
Base()
{
printf("Base()n");
}
|
Since you're deriving from it, you ordinarily should
make the destructor virtual if there's any chance
you'll use a Base pointer to refer to a Derived
object.
| Quote: | ~Base()
{
printf("~Base()n");
}
};
class Derived:public Base
{
public:
Derived()
{
printf("Derived()n");
}
void myConst() const
{
printf("Derived's myConst function x=%d",x);
}
~Derived()
{
printf("~Derived()n");
}
int x;
};
main()
|
main returns int. Always. Please see the FAQ.
| Quote: | {
Derived *dptr;
dptr=(Derived *)new Base();
|
OK, so you've casted it to something it's not.
Probably better to get in the habit of using a
static_cast<> in these circumstances...
undefined behavior.
undefined behavior.
| Quote: | delete dptr;
}
In the above code "dptr->myConst()" succeeds
without giving any error
on Solaris, but generates an exception when ran on
Winodws after
compiling in VC++
My Question is Why does it not fail?
|
Your program has undefined behavior. "Appearing to
work" and "crashing the computer" both fall in the
category of undefined behavior. In fact, "appearing
to work the first 5000 times I run it, then crashing
on the 5001st time" also falls in the category of
undefined behavior. Presumably what is actually
happening - although it is obviously
implementation-dependent - is that the computer is
trashing random memory when it assigns to the
nonexistent x member. On the Solaris, it so happens
that trashing that memory doesn't cause any
immediately visible effects - it may even be trashing
memory that didn't have anything important in it
anyway. On the Visual C++ platform, presumably you
weren't so lucky.
By the way, I don't know what you mean by "exception."
A C++ exception? A hardware exception? A .NET
structured exception? That is an overloaded term, and
you haven't provided enough info to determine which
meaning you intended. But I suppose that any of those
still falls in the category of undefined behavior.
Best regards,
Tom
__________________________________
Do you Yahoo!?
Yahoo! Mail SpamGuard - Read only the mail you want.
http://antispam.yahoo.com/tools
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Jonathan Turkanis Guest
|
Posted: Sat Feb 21, 2004 1:59 pm Post subject: Re: typecasting the base class to derived class. |
|
|
"cman" <complangman (AT) yahoo (DOT) com> wrote in message:
<snip>
| Quote: | main()
{
Derived *dptr;
dptr=(Derived *)new Base();
dptr->x=10;
dptr->myConst();
delete dptr;
}
|
<snip>
| Quote: | | My Question is Why does it not fail?
|
It is undefined behavior, by 5.4/5 and 5.2.9/5. No diagnostic or
explosion is required.
Jonathan
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Ulrich Eckhardt Guest
|
Posted: Sat Feb 21, 2004 4:14 pm Post subject: Re: typecasting the base class to derived class. |
|
|
cman wrote:
| Quote: | Derived *dptr;
dptr=(Derived *)new Base();
dptr->x=10;
|
Undefined behaviour, all bets are off. Just don't do that.
Uli
--
Questions ?
see C++-FAQ Lite: http://parashift.com/c++-faq-lite/ first !
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Francis Glassborow Guest
|
Posted: Sat Feb 21, 2004 4:25 pm Post subject: Re: typecasting the base class to derived class. |
|
|
In message <20040220224944.15405.qmail (AT) web60907 (DOT) mail.yahoo.com>, Thomas
Tutone <thomas8675309 (AT) yahoo (DOT) com> writes
| Quote: | "cman" <complangman (AT) yahoo (DOT) com> wrote:
#include
class Base
{
public:
Base()
{
printf("Base()n");
}
Since you're deriving from it, you ordinarily should
make the destructor virtual if there's any chance
you'll use a Base pointer to refer to a Derived
object.
|
To be absolutely precise, if there is any chance that you will try to
delete a dynamic instance through a base-class pointer.
--
Francis Glassborow ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Pete Becker Guest
|
Posted: Sat Feb 21, 2004 6:23 pm Post subject: Re: typecasting the base class to derived class. |
|
|
Francis Glassborow wrote:
| Quote: |
In message <20040220224944.15405.qmail (AT) web60907 (DOT) mail.yahoo.com>, Thomas
Tutone <thomas8675309 (AT) yahoo (DOT) com> writes
"cman" <complangman (AT) yahoo (DOT) com> wrote:
#include
class Base
{
public:
Base()
{
printf("Base()n");
}
Since you're deriving from it, you ordinarily should
make the destructor virtual if there's any chance
you'll use a Base pointer to refer to a Derived
object.
To be absolutely precise, if there is any chance that you will try to
delete a dynamic instance through a base-class pointer.
|
There's always a chance that someone will write incorrect code. The true
test is not probabilistic. It is whether the design of the base class
calls for deletion of derived types through base pointers.
--
Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
stelios xanthakis Guest
|
Posted: Sun Feb 22, 2004 1:47 am Post subject: Re: typecasting the base class to derived class. |
|
|
Pete Becker <petebecker (AT) acm (DOT) org> wrote
| Quote: | There's always a chance that someone will write incorrect code. The true
test is not probabilistic. It is whether the design of the base class
calls for deletion of derived types through base pointers.
|
The problem is an illegal downcast. This is why the new
C++ casts (static/reintepret/dynamic/const) were invented
by its designers: they can warn on such errors.
As long as a base object is casted to a derrived object,
the program is ill. It may not crash because accedentially
the objects have the same size, but it is not ok.
sx
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Pete Becker Guest
|
Posted: Sun Feb 22, 2004 5:31 pm Post subject: Re: typecasting the base class to derived class. |
|
|
stelios xanthakis wrote:
| Quote: |
Pete Becker <petebecker (AT) acm (DOT) org> wrote
There's always a chance that someone will write incorrect code. The true
test is not probabilistic. It is whether the design of the base class
calls for deletion of derived types through base pointers.
The problem is an illegal downcast.
|
Please don't snip context. I was replying to these assertions:
| Quote: | Since you're deriving from it, you ordinarily should
make the destructor virtual if there's any chance
you'll use a Base pointer to refer to a Derived
object.
To be absolutely precise, if there is any chance that you will try to
delete a dynamic instance through a base-class pointer.
|
Illegal downcasts are not involved here. The design issue raised here is
when classes should have virtual destructors.
--
Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
kanze@gabi-soft.fr Guest
|
Posted: Mon Feb 23, 2004 7:41 pm Post subject: Re: typecasting the base class to derived class. |
|
|
Pete Becker <petebecker (AT) acm (DOT) org> wrote
| Quote: | Francis Glassborow wrote:
In message <20040220224944.15405.qmail (AT) web60907 (DOT) mail.yahoo.com>, Thomas
Tutone <thomas8675309 (AT) yahoo (DOT) com> writes
"cman" <complangman (AT) yahoo (DOT) com> wrote:
#include
class Base
{
public:
Base()
{
printf("Base()n");
}
Since you're deriving from it, you ordinarily should make the
destructor virtual if there's any chance you'll use a Base pointer
to refer to a Derived object.
To be absolutely precise, if there is any chance that you will try
to delete a dynamic instance through a base-class pointer.
There's always a chance that someone will write incorrect code. The
true test is not probabilistic. It is whether the design of the base
class calls for deletion of derived types through base pointers.
|
Well, there is one other case when need a virtual function: when the
design calls for a checked cast from Base* to Derived*. That's what the
original poster did, and given the original problem (and not just the
bit of code you were responding to), one could argue that the "correct"
solution would have been to add a virtual destructor to Base, and to use
reinterpret_cast. That way, he would have gotten the exception or the
error he seems to want.
--
James Kanze GABI Software mailto:kanze (AT) gabi-soft (DOT) fr
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Jim Melton Guest
|
Posted: Tue Feb 24, 2004 3:28 am Post subject: Re: typecasting the base class to derived class. |
|
|
<kanze (AT) gabi-soft (DOT) fr> wrote
| Quote: | Pete Becker <petebecker (AT) acm (DOT) org> wrote in message
news:<403786D3.5AE43460 (AT) acm (DOT) org>...
Francis Glassborow wrote:
In message <20040220224944.15405.qmail (AT) web60907 (DOT) mail.yahoo.com>,
Thomas
Tutone <thomas8675309 (AT) yahoo (DOT) com> writes
"cman" <complangman (AT) yahoo (DOT) com> wrote:
#include <stdio.h
class Base
{
public:
Base()
{
printf("Base()n");
}
Since you're deriving from it, you ordinarily should make the
destructor virtual if there's any chance you'll use a Base pointer
to refer to a Derived object.
To be absolutely precise, if there is any chance that you will try
to delete a dynamic instance through a base-class pointer.
There's always a chance that someone will write incorrect code. The
true test is not probabilistic. It is whether the design of the base
class calls for deletion of derived types through base pointers.
Well, there is one other case when need a virtual function: when the
design calls for a checked cast from Base* to Derived*. That's what the
original poster did, and given the original problem (and not just the
bit of code you were responding to), one could argue that the "correct"
solution would have been to add a virtual destructor to Base, and to use
reinterpret_cast. That way, he would have gotten the exception or the
error he seems to want.
|
OK, you lost me. The OP's problem was that he used a C-style cast, which
blindly does precisely what you tell it. I would have thought that
dynamic_cast would have been the correct solution (presuming any virtual
functions at all -- usually required to achieve polymorphism).
Here's my touchstone for C++-style casts:
static_cast - invoke defined conversion
const_cast - add/remove constness
dynamic_cast - typesafe down-cast
reinterpret_cast - DWIM (do what i mean): interpret the bits of the argument
as if they were the template type
Of the four, I think reinterpret_cast is the hardest to get right. But I
didn't think you would get any type-safety from it. Is it possible your
recommendation is a typo?
--
Opinions posted are those of the author.
My company doesn't pay me enough to speak for them.
</disclaimer>
--
Jim Melton
Software Architect, Fusion Programs
Lockheed Martin IS&S
(303) 971-3846
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
stelios xanthakis Guest
|
Posted: Tue Feb 24, 2004 7:26 pm Post subject: Re: typecasting the base class to derived class. |
|
|
Pete Becker <petebecker (AT) acm (DOT) org> wrote
| Quote: | stelios xanthakis wrote:
Pete Becker <petebecker (AT) acm (DOT) org> wrote
There's always a chance that someone will write incorrect code. The true
test is not probabilistic. It is whether the design of the base class
calls for deletion of derived types through base pointers.
The problem is an illegal downcast.
Please don't snip context. I was replying to these assertions:
|
I'm sorry. Just wanted to point out what's really wrong before
the thread went too far.
| Quote: | Since you're deriving from it, you ordinarily should
make the destructor virtual if there's any chance
you'll use a Base pointer to refer to a Derived
object.
To be absolutely precise, if there is any chance that you will try to
delete a dynamic instance through a base-class pointer.
Illegal downcasts are not involved here. The design issue raised here is
when classes should have virtual destructors.
|
That would had been the case if the code was
Base *b = new Derrived;
The case:
Derrived *d = (Derrived*) new Base;
Is ill and because there are people reading clc++ who are not
experts, we wouldn't want to confuse this ill program with the
virtual dtors.
BTW, to contribute to the discussion, I think a virtual
destructor is also needed in this case:
class A { int x; };
class B { int y; };
class C : A, B { int z; };
int f ()
{
B *b = new C;
delete b;
}
Despite the fact that the classes have no dtors, a virtual dtor
must be present because the above crashes. How does the std
describes this? I don't know...
Cheers,
Stelios
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
kanze@gabi-soft.fr Guest
|
Posted: Tue Feb 24, 2004 7:29 pm Post subject: Re: typecasting the base class to derived class. |
|
|
Jim Melton <jim.melton (AT) lmco (DOT) com> wrote
| Quote: | Since you're deriving from it, you ordinarily should make the
destructor virtual if there's any chance you'll use a Base
pointer to refer to a Derived object.
To be absolutely precise, if there is any chance that you will
try to delete a dynamic instance through a base-class pointer.
There's always a chance that someone will write incorrect
code. The true test is not probabilistic. It is whether the design
of the base class calls for deletion of derived types through base
pointers.
Well, there is one other case when need a virtual function: when the
design calls for a checked cast from Base* to Derived*. That's what
the original poster did, and given the original problem (and not
just the bit of code you were responding to), one could argue that
the "correct" solution would have been to add a virtual destructor
to Base, and to use reinterpret_cast. That way, he would have
gotten the exception or the error he seems to want.
OK, you lost me.
|
No problem. Pete said that you needed a virtual destructor if and only
if the design called for deletion of derived types through a pointer to
base types. Given that the original poster was downcasting, and that he
wanted an error, he probably wanted to use dynamic_cast. Which only
works if there is at least one virtual function. In the absense of any
other virtual function, a virtual destructor is as good a choice as
any. Another possible reason for a virtual destructor.
| Quote: | The OP's problem was that he used a C-style cast, which blindly does
precisely what you tell it. I would have thought that dynamic_cast
would have been the correct solution (presuming any virtual functions
at all -- usually required to achieve polymorphism).
|
Exactly. And as there weren't any other virtual functions in the
example:-).
| Quote: | Here's my touchstone for C++-style casts:
static_cast - invoke defined conversion
const_cast - add/remove constness
dynamic_cast - typesafe down-cast
reinterpret_cast - DWIM (do what i mean): interpret the bits of the argument
as if they were the template type
Of the four, I think reinterpret_cast is the hardest to get right. But
I didn't think you would get any type-safety from it. Is it possible
your recommendation is a typo?
|
Ooops. Very much so. I meant dynamic_cast, of course. (The others
wouldn't require any virtual functions. In a very real sense, they are
all "do as I say, and stop asking questions" types of operators.)
--
James Kanze GABI Software mailto:kanze (AT) gabi-soft (DOT) fr
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Francis Glassborow Guest
|
Posted: Wed Feb 25, 2004 2:39 pm Post subject: Re: typecasting the base class to derived class. |
|
|
In message <8a018872.0402240653.15835ae4 (AT) posting (DOT) google.com>, stelios
xanthakis <mayall (AT) freemail (DOT) gr> writes
| Quote: | BTW, to contribute to the discussion, I think a virtual
destructor is also needed in this case:
class A { int x; };
class B { int y; };
class C : A, B { int z; };
int f ()
{
B *b = new C;
delete b;
}
Despite the fact that the classes have no dtors, a virtual dtor
must be present because the above crashes. How does the std
describes this? I don't know...
|
No, if it there were virtual dtors there would not be a problem
(actually I am surprised that the above code does anything worse than
leak memory). Of course there are dtors because currently there is no
way to avoid every class object having a dtor (well you might declare
one and then not define it but then the linker would complain).
--
Francis Glassborow ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Pete Becker Guest
|
Posted: Wed Feb 25, 2004 3:04 pm Post subject: Re: typecasting the base class to derived class. |
|
|
[email]kanze (AT) gabi-soft (DOT) fr[/email] wrote:
| Quote: |
No problem. Pete said that you needed a virtual destructor if and only
if the design called for deletion of derived types through a pointer to
base types.
|
No, I said that IN THE CONTEXT TO WHICH I WAS REPLYING, the true rule
was that you need a virtual destructor only if your class design calls
for deleting objects of derived types through pointers to the base type.
That was in contrast to the assertion that "[t]o be absolutely precise,
if there is any chance that you will try to delete a dynamic instance
through a base-class pointer [you should have a virtual destructor]."
The point was that decisions about virtual destructors should be based
on concrete design criteria, not on general principles and not on
guesses.
--
Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Thomas Tutone Guest
|
Posted: Wed Feb 25, 2004 3:05 pm Post subject: Re: typecasting the base class to derived class. |
|
|
"stelios xanthakis" <mayall (AT) freemail (DOT) gr> wrote:
[snip]
| Quote: | BTW, to contribute to the discussion, I think a
virtual
destructor is also needed in this case:
class A { int x; };
class B { int y; };
class C : A, B { int z; };
|
OK, C inherits privately from A & B.
| Quote: | int f ()
{
B *b = new C;
|
That shouldn't even compile - B is a private base
class of C.
| Quote: | delete b;
}
Despite the fact that the classes have no dtors,
|
Sure they do - well they would but for the fact that
your code doesn't compile - they would have the
compiler-generated default destructor. I think you
mean they have no user-defined destructors, but so
what?
| Quote: | a virtual dtor
must be present because the above crashes. How does
the std
describes this? I don't know...
|
OK, your example includes both private inheritance and
multiple inheritance, both of which are red herrings
that distract from the issue. Let me simplify your
example:
class Base {};
class Derived : public Base { int i; };
int main()
{
Base* b(new Derived);
delete b;
}
That's undefined behavior, because Base doesn't have a
virtual destructor (although it does have a
nonvirtual, compiler-generated destructor). Since
it's undefined, "crashes" falls within the type of
behavior the program could exhibit.
Best regards,
Tom
__________________________________
Do you Yahoo!?
Yahoo! Mail SpamGuard - Read only the mail you want.
http://antispam.yahoo.com/tools
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|