c++smart-pointersdefault-arguments

What's the best and safest way to dynamically create object of derived class passed as default function argument?


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


Solution

  • 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.