How to pass a default parameter for std::shared_ptr<PureVirtualClass>

9.4k views Asked by At

I have a function of type

virtual void foo(bla, bla, bla, std::shared_ptr<LoggerInterface> logger) = 0;

And I want to pass a default parameter with NULL pointer, something like:

virtual void foo(bla, bla, bla, std::shared_ptr<LoggerInterface> logger = NULL) = 0;

So that in implementation, if logger is NULL I do nothing with it, otherwise I use the logger.

I've tried to look for a solution but cannot find..

UPD: Duplicate claim is irrelevant, I am asking about default NULL parameter.

Is it possible that gcc 4.4 doesn't support nullptr?

3

There are 3 answers

4
Christophe On

With a C++11 compliant compiler

This should work with either NULL or nullptr the latter being the recommended form for C++. The only condition is that you compile it for c++11 or higher (see comment of jamek about the command line options for gcc).

struct B {
    virtual void foo(int blablabla, std::shared_ptr<LoggerInterface> logger = nullptr) = 0;
};

struct D : B {
    void foo(int blablabla, std::shared_ptr<LoggerInterface> logger) override {
        std::cout << "foo: "<<blablabla<<" "<< logger<<std::endl; 
    }
};

int main() {
    D d; 
    B *b=&d;
    b->foo(15); 
}

See online demo

Important remark about default parameters

Note that the default parameter is not intrinsic to the function itself, but to the context in which the default value was declared. In the example above:

  • b->foo(15) works, because the function is accessed using the B class for which a default parameter is defined.
  • d.foo(15) won't even compile, despite both referring to the same function. This is because for the D class I didn't declare a default value in the definition of the override.
  • I could even have a different default value for both definitions (see in the online demo)

Limitated implementation of C++11 in GCC 4.4

Indeed, nullptr was introduced with GCC 4.6 and you have to wait GCC 4.8.1 for a full C++11 implementation.

In fact GCC 4.4.0 was released in 2009 and the first sub-release after the official approval of the standard in august 2011 was GCC 4.4.7.

0
skypjack On

You can simply do this:

virtual void foo(bla, bla, bla, std::shared_ptr<LoggerInterface> logger = {}) = 0;

As you can see here, both the empty constructor and nullptr give the same result, that is:

Constructs a shared_ptr with no managed object, i.e. empty shared_ptr

0
jhuai On

IMHO, if you are looking to pass a null pointer, then do not use shared_ptr as the argument type. Instead use a raw pointer. This way, you don't have to figure out the arcane default value for a shared pointer.

And you can keep the benefits of shared_ptr by passing the embedded raw pointer. In your case, it looks like below.

// In declaration file
virtual void foo(bla, bla, bla, LoggerInterface* logger = nullptr) = 0;


std::shared_ptr<LoggerInterface> loggerPtr(new LoggerInterface());
// or
std::shared_ptr<LoggerInterface> loggerPtr;

// Call the function
Bar bar;
bar.foo(bla, bla, bla, loggerPtr ? loggerPtr.get() : nullptr);
...