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

时间:2016-12-29 14:41:57

标签: c++ c++11 shared-ptr default-parameters

我有一个类型

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

我想用NULL指针传递一个默认参数,如:

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

所以在实现中,如果logger是NULL,我什么也不做,否则我会使用记录器。

我试图找一个解决方案但找不到..

UPD:重复声明无关紧要,我问的是默认的NULL参数。

gcc 4.4是否可能不支持nullptr?

3 个答案:

答案 0 :(得分:3)

你可以这样做:

<div id="header">
    <img src="images/header-1.jpg" style="max-width:100%; height:auto;"/>
</div>
<div id="headerTitle">
    <h2>header</h2>
    <h3><em>subhead</em></h3>
</div>   
<nav id="navbar">
    <div id="enter">
        <div class="numberCircle"><span>5</span></div>
        <div class="pg-nav">
            <ul class="nav-links">
                <li><a href="#a">A</a></li>
                <li><a href="#b">B</a></li>
                <li><a href="#c">C</a></li>
                <li><a href="#d">D</a></li>
            </ul>
        </div>
    </div>
</nav>

<style>
#navbar {
letter-spacing: 1px;
margin: 20px 0 20px 0;
width: 100%;
}
.fixedtop {
position: fixed;
z-index: 100;
width: 100%;
top: 0;
}
#enter {
background-attachment: scroll;
background-clip: border-box;
background-color: #696969;
background-image: none;
background-origin: padding-box;
background-position: 0 0;
background-repeat: repeat;
background-size: auto auto;
height: 30px;
line-height: 10px;
padding: 10px;
text-align: center;
border-bottom: #97233f solid 2px;
/* width: 100%; */
/* z-index: 9999; */
}
.pg-nav {
width: 100%;
margin: 0 auto;
text-align: left;
}
.pg-nav ul {
list-style-type: none;
margin: 0 0 0 10px;
padding: 0;
overflow: hidden;
position: relative;  
display: inline-block;    
}
.pg-nav li {
float: left;
padding: 12px;
font-weight: 900;
}
.pg-nav li a {
display: block;
font-family: "Lato",sans-serif;
color: #fff;
font-size: 11px;     
font-weight: 900;
text-decoration: none;
text-transform: uppercase;      
}
@media (max-width: 500px) {
.pg-nav li {width:100%; padding:5px;}
}
.pg-nav li a:hover {
color: #97233f; 
}
.numberCircle {
border-radius: 50%;
width: 28px; 
font-size: 21px;
border: 2px solid #fff;
float: left;
}
.numberCircle span {
text-align: center;
line-height: 28px;
display: block;
color: #fff;
}
</style>

<script>
$(function() {
var distance = $('#navbar').offset().top,
$window = $(window);

$window.scroll(function() {
$('#navbar').toggleClass('fixedtop', $window.scrollTop() >= distance)
});
});
</script>

正如您所见here,空构造函数和virtual void foo(bla, bla, bla, std::shared_ptr<LoggerInterface> logger = {}) = 0; 都给出了相同的结果,即:

  

构造一个没有托管对象的shared_ptr,即空shared_ptr

答案 1 :(得分:1)

使用符合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); 
}

请参阅online demo

有关默认参数的重要说明

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

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

在GCC 4.4中限制C ++ 11的实现

确实,nullptr是在GCC 4.6中引入的,你必须等待GCC 4.8.1获得full C++11 implementation

事实上,GCC 4.4.0是released in 2009,并且august 2011中正式批准该标准后的第一个子版本是GCC 4.4.7。

答案 2 :(得分:0)

恕我直言,如果您要传递空指针,请不要使用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);
...