Forced downcast - when will it work?

S

Steve Schlesinger

In the following code I do a forced downcast of an A object to its

derivative B If I declare all member variables in A and only add

member functions in B, will this always work?



The test case vith Vis Studio 6.0 cl.exe works as expected.



class A

{

public:

int n;

};



class B : public A

{

public:

void f() { printf( "In B::f() n=%d\n", n); }

};





int main(int argc, char* argv[])

{

A a;

a.n=2;



B b;

b.n = 1;

b.f();



B* pb = static_cast<B*>(&a);



pb->f();



return 0;

}



// Output

//

//In B::f() n=1

//In B::f() n=2



steve<at>schlesinger<dot>com
 
D

David Harmon

class B : public A
B* pb = static_cast<B*>(&a);

Those three lines say there is no guarantee it will ever work.
We could speculate on what you might get away with, but so what?

Casting a (A*) to a (B*) is guaranteed only if the pointer actually
points to a B object. It might for example "work" by pure bad luck
while you are debugging, then fail after you ship it to a customer.
 
J

Jeff Schwab

Steve said:
In the following code I do a forced downcast of an A object to its
derivative B If I declare all member variables in A and only add
member functions in B, will this always work?

The test case vith Vis Studio 6.0 cl.exe works as expected.

class A
{
public:
int n;
};

class B : public A
{
public:
void f() { printf( "In B::f() n=%d\n", n); }
};

int main(int argc, char* argv[])
{
A a;
a.n=2;

B b;
b.n = 1;
b.f();

B* pb = static_cast<B*>(&a);
pb->f();

return 0;
}

// Output
//
//In B::f() n=1
//In B::f() n=2

steve<at>schlesinger<dot>com

No, it will not work if A has a virtual member function called "f()",
and possibly not if B has any other sub-objects. Suck it up and create
a real B when you need one, e.g.:

struct A
{
A( int i =0 ): n( i ) { }

int n;
};

#include <iostream>

class B
{
public:
B( int n =0 ): m_a( A( n ) ) { }
void f() { std::cout << "In B::f() n=" << m_a.n << '\n'; }
void a( A const& a ) { m_a = a; }
private:
A m_a;
};

int main( )
{
A a( 2 );
B b( 1 );

b.f( );
b.a( a );
b.f( );
}

// Output
//
//In B::f() n=1
//In B::f() n=2
 

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

Forum statistics

Threads
473,764
Messages
2,569,567
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top