如何为std::shared_ptr<PureVirtualClass>传递默认参数

13

我有一个类型为

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

我想要传递一个带有空指针的默认参数,类似于:

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

所以在实现中,如果记录器是 NULL ,我就不做任何操作,否则我会使用该记录器。

我尝试寻找解决方案,但找不到...

更新:重复声明无关紧要,我正在询问默认的NULL参数。

是否可能gcc 4.4不支持nullptr?


3
应该使用nullptr而不是NULL。后者是一个宏,很可能是0,前者才是表示空指针的正确字面量。 - Cory Kramer
我已经尝试过了,但还是出现了编译错误: 错误:在此作用域中未声明“nullptr”。 - Eric Abramov
这个问题不是“虚函数可以有默认参数”的重复。函数是虚拟的这一事实与此问题无关。 - IanPudney
3
在Linux上,您需要添加"-std=c++11"参数。 - jamek
3个回答

8
您可以简单地执行以下操作:
virtual void foo(bla, bla, bla, std::shared_ptr<LoggerInterface> logger = {}) = 0;

正如您可以看到这里,空构造函数和nullptr会得出相同的结果,即:

构造一个没有受管理对象的shared_ptr,即空的shared_ptr。


3

使用符合C++11标准的编译器

这应该可以使用 NULLnullptr,后者是C++中推荐的形式。唯一的条件是您需要将其编译为C++11或更高版本(请参见jamek关于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); 
}

查看在线演示

关于默认参数的重要说明

请注意,默认参数不是函数本身固有的,而是定义默认值的上下文所特有的。在上面的例子中:

  • b->foo(15)可以工作,因为使用了为其定义默认参数的类访问函数
  • d.foo(15)甚至无法编译,尽管两者都引用相同的函数。这是因为对于类,我在覆盖定义中没有声明默认值。
  • 我甚至可以为这两个定义设置不同的默认值(请参见在线演示)。

GCC 4.4中C++11的受限实现

实际上,nullptr是在GCC 4.6中引入的,而您必须等待GCC 4.8.1才能获得完整的C++11实现

事实上,GCC 4.4.0于2009年发布,而在2011年8月正式批准标准后的第一个次版本是GCC 4.4.7。


谢谢,但问题在于gcc 4.4不支持所有的C++11特性,比如nullptr。 - Eric Abramov
Indeed:nullptr 仅从 4.6 版本开始引入! - Christophe
@EricAbramov和And,4.4.0追溯至2009年,而4.4.7是在c++11正式批准后的第一个版本。 - Christophe
是的,我应该等到我们公司的生产流水线升级到gcc 4.6。 - Eric Abramov

0

在我看来,如果你想传递一个空指针,那么不要使用 shared_ptr 作为参数类型。而是使用原始指针。这样,你就不必为 shared_ptr 的神秘默认值烦恼了。

通过传递嵌入的原始指针,你可以保留 shared_ptr 的好处。在你的情况下,代码如下所示。

// 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);
...



网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接