Casting from base to derived class in base constructor

P

pastbin

Dear members,

The following code compiles and runs fine on MSVC++ 2005 Express
edition.
Warning level at maximum and nothing wrong is reported.

This is a minimal code I wrote in order to test something for my
personal needs.
I'm not sure if the code is "legal" because I'm downcasting in a
constructor of a base class
to call a member of another base class of a different branch in the
hierarchy.

//------------
#include <iostream>

template<typename Derived>
struct aspect
{
aspect() { // constructor
Derived* derived = static_cast<Derived*>(this); // downcast
derived->handler_member(); // call a member of a base class of
derived
}
};

template<typename Derived>
struct handler
{
void handler_member() {
std::cout << "handler";
}
};

template<typename Derived, template<class> class Handler>
struct win : public Handler<Derived>
{
};

struct my_win : public win<my_win, handler>
, public aspect<my_win>
{
void dummy() {
std::cout << "ok";
}
};

int main() {
my_win w; // print "handler" as expected
w.dummy(); // print "ok" as expected
return 0;
}
//------------

Isn't this code somewhat esoteric ?

Thank you

mark
 
J

James Kanze

The following code compiles and runs fine on MSVC++ 2005
Express edition. Warning level at maximum and nothing wrong
is reported.
This is a minimal code I wrote in order to test something for
my personal needs. I'm not sure if the code is "legal"
because I'm downcasting in a constructor of a base class to
call a member of another base class of a different branch in
the hierarchy.
//------------
#include <iostream>
template<typename Derived>
struct aspect
{
aspect() { // constructor
Derived* derived = static_cast<Derived*>(this); // downcast
derived->handler_member(); // call a member of a base class of derived

This is undefined behavior. The cast itself is undefined
behavior, to begin with (but I can't really imagine an
implementation where it would fail). The call to the function
is undefined behavior, and may in fact cause problems in all but
the simplest cases.

Don't do it.
template<typename Derived>
struct handler
{
void handler_member() {
std::cout << "handler";
}
};
template<typename Derived, template<class> class Handler>
struct win : public Handler<Derived>
{
};

struct my_win : public win<my_win, handler>
, public aspect<my_win>
{
void dummy() {
std::cout << "ok";
}
};
int main() {
my_win w; // print "handler" as expected
w.dummy(); // print "ok" as expected
return 0;}

Isn't this code somewhat esoteric ?

More than esoteric, it's undefined behavior, and even if it
happens to work, it is fragile and unmaintainable.

Please explain what you are trying to do. There's likely a
clean solution for it.
 
P

pastbin

More than esoteric, it's undefined behavior, and even if it
happens to work, it is fragile and unmaintainable.

Please explain what you are trying to do. There's likely a
clean solution for it.

Thank you for the reply.
The code:

Derived* derived = static_cast<Derived*>(this);

is undefined behavior because we are in a base constructor ?
Isn't it ?

What I'm trying to do is close to "delegate to a sister class":
http://www.parashift.com/c++-faq-lite/multiple-inheritance.html#faq-25.10
But at construction time if possible..

Using templates I was in hope of avoiding virtual functions.

Thank you

mark
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,965
Messages
2,570,148
Members
46,710
Latest member
FredricRen

Latest Threads

Top