This question fundamentally has nothing to do with structs, or classes, or polymorphism, (though the solution does require the latter).
It's about trying to declare objects of different types, conditionally, without running afoul of block scoping. The simple answer is that you can't.
The usual approach is to use a late-initialised smart pointer instead:
#include <memory>
#include <cstdlib>
struct A { virtual ~A() {} };
struct B : A {};
struct C : A {};
void f(A&);
int main()
{
srand(time(0));
const int x = rand();
#if 0
/** Can't do this: **/
if (x > 500)
B obj;
else
C obj;
f(obj);
#endif
/** Can do this: **/
std::unique_ptr<A> ptr;
if (x > 500)
ptr.reset(new B);
else
ptr.reset(new C);
f(*ptr);
#if 0
/** Some older examples may propose this: **/
A* ptr = NULL;
if (x > 500)
ptr = new B;
else
ptr = new C;
f(*ptr);
delete ptr;
ptr = NULL;
#endif
}
Since f
accepts a reference, polymorphic is maintained even though you're feeding it a A
.
Typically you'd actually invoke a member function through ptr
, using virtual dispatch to ensure that the correct code is executed:
std::unique_ptr<A> ptr;
if (x > 500)
ptr.reset(new B);
else
ptr.reset(new C);
ptr->someFunction();
No function overloads required.