1

Regarding this question i saw all the answers are using pointer to base class(Base *baseObject) and then use new keyword to instantiate different implementations of base class.

let's say if there is a Base Class like this:

class Base
{
    public:
           int Id;
}

and other classes like this:

class A : public Base {...}
class B : public Base {...}

is there anyway to instantiate a Base Class object Conditionally but without using pointers, like this:

Base a;
if (...) a = new A();
else if (...) a = new B()

Edit:

Based on comments there is no force to use new keyword.

Community
  • 1
  • 1
yekanchi
  • 813
  • 1
  • 12
  • 30
  • Using `new` only makes sense for pointers, it is asking for memory to store a class and the pointer will point to that memory. In your last section of code `Base a;` already takes up local memory by being declared like that because `a` is not a pointer – asimes Feb 05 '19 at 15:11
  • there is no force to use `new` keyword – yekanchi Feb 05 '19 at 15:32

4 Answers4

2

You can use Reference instead of pointer.

For example:

Derived d;
Base &b = d;
Loc Tran
  • 1,170
  • 7
  • 15
1

The thing is, when using value instead of pointer, you always get values of the same type. So for this case:

Base b;

The variable b cannot be anything but an instance of b. Even if you do that:

Derived d;
Base b = d; // d is sliced into b

The variables d and b are different instances. To do the assignement, the compiler must convert the value of d into a value of type Base, much like this:

double d = 9.5;
int i = d; // i is 9, it sliced the .5

So you must have some kind of reference, or some kind of variable that allows varying types.

Using a reference/pointer

This is usually how polymorphism is done. You make b a reference type that can refer to any instance of object that extends Base.

std::unique_ptr<Base> b = std::make_unique<Derived>();

This creates a unique pointer of type Derived, and assign it to a unique pointer of type Base. b now points to the instance of a Derived object.

If instead you want to use reference, you must have a variable that stays alive enough time to use it, something like that:

void foo(Base& refToBase);

void bar() {
    Derived d;
    foo(d);
} // d is guaranteed to die here.

Using a variant

A variant is a type that can have a value of multiple types. It can only contain one value, so it 'varies' between types.

For example:

std::variant<int, std::string> v;

v = 12;
v = "text"; 

So you can use that to create a variable that can vary between derived types:

std::variant<A, B> a_or_b;

if(...) {
    a_or_b = A{};
} else {
    a_or_b = B{};
}

std::visit(
    [](Base& b) { /* do stuff with the base */ },
    a_or_b
);
Guillaume Racicot
  • 39,621
  • 9
  • 77
  • 141
0

I don't think so.

  1. the keyword new returns a pointer to a newly created object. That's why you need a base class pointer (or specific one) to store it.

  2. But the bigger issue in your case is Base a;. It already creates an object of the class Base. So you try to assign a pointer to a new object from the derived class to a different, already existing object of your base class.

Just use a pointer and everything is fine:

Base* a;
if (...) a = new A();
else if (...) a = new B();
izlin
  • 2,129
  • 24
  • 30
0

is there anyway to instantiate a Base Class object Conditionally but without using pointers

Sure:

if(condition) {
    A a;
} else {
    B b;
}
eerorika
  • 232,697
  • 12
  • 197
  • 326