Home > Software engineering >  What's the best and safest way to dynamically create object of derived class passed as default
What's the best and safest way to dynamically create object of derived class passed as default

Time:01-28

I have a classes

class Base {
public:
    virtual ~Base() {}
    virtual string returnString() = 0;
};

class B : public A {
public:
     string returnString() { return "string"; }
}

class C : public A {
public:
     string returnString() { return ""; }
}

and function

string returnStringFunction(...);

I want to be able to pass object of type C but by default, I want this function to use dynamically created object of type B.

I remember using something like this:

string returnStringFunction(const A& a = *std::make_unique<B>()) 

or

string returnStringFunction(const std::unique_ptr<A> a = std::make_unique<B>()) 

Example function body:

string returnStringFunction(...) {
    return a->returnString();
}

But both of these solutions even though they normally compile and work on my "sandbox" environment, they generate SIGFAULT on workspace. Any idea what's causing it or how to better solve it?

Thanks in advance

CodePudding user response:

As mentioned in comments, const std::unique_ptr<A> a = std::make_unique<B>() should be fine, while the other is not. However, in general default arguments are only second class citizens in C . If nothing speaks against it I would prefer to overload the function.

If you want the funcion to be callable with and without argument you can provide two overloads:

string returnStringFunction(const Base&);
string returnStringFunction() {
     B b;
     returnStringFunction(b);
}

Not sure why you would dynamically allocate the B here, but if you want you can.

CodePudding user response:

I'd suggest avoiding dynamic memory allocations since there are cheaper ways to do it (unless you have a very strong reason to do it). In this case you can use a const reference:

string returnStringFunction(const A& a = B{}) ...

Obviously, this limits your function to constant methods, but as far as you have described your problem it should work for you.

If your default object is expensive to construct you can use a singleton or similar as default value:

class B : public A {
public:
     string returnString() { return "string"; }

     static B sDefault;
};

// remember to define it somewhere
B B::sDefault;

// ...
string returnStringFunction(const A& a = B::sDefault) ...
  • Related