可以在新的C ++ 11中创建可选引用吗?

时间:2011-11-28 20:07:21

标签: c++ constructor c++11

鉴于新的C ++ 11标准及其中引入的移动语义,是否可以为构造函数引用创建默认值?这里Default value to a parameter while passing by reference in C++据说没有,但也许新标准允许一些棘手。

基本上我想要的是使用默认对象进行正常使用,并传递一个模拟对象,该对象记录主机对象在测试阶段所做的所有调用。它应该像

class A {
   B& b;
   public:
       A(B & b = B()){} // This does not work
}

当测试我想要的是

BMock bMock;
A a(bMock);
bMock.getStatistics();

有什么想法吗?

3 个答案:

答案 0 :(得分:4)

这个怎么样:

class Foo
{
  B default_B;

public:

  std::reference_wrapper<B> b;

  Foo() : b(std::ref(default_B)) { }

  Foo(B & br) b(std::ref(br)) { }
};

这是一个可能更轻量级的替代想法,但在默认情况下以动态分配为代价:

#include <memory>

class Foo
{
  std::unique_ptr<B> pB;

public:

  std::reference_wrapper<B> b;

  Foo() : pb(new B), b(std::ref(*pb)) { }

  Foo(B & br) pb(), b(std::ref(br)) { }
};

答案 1 :(得分:1)

是的,默认的初始化表达式是一个临时对象,它将绑定到右值引用。但是,您需要通过std::move传递非临时对象才能将他们绑定到引用。

通常通过std::move传递内容表示它将被被调用的函数销毁。该标准甚至将std::move的结果称为“到期值”;虽然它没有真正的语义必然性,但它是一个非常强大的惯例。

所以,你可以做到这一点,但要小心。

仔细观察您的示例,您希望在b内保留对a的引用,这意味着如果没有使用参数,则无处永久存储建议的默认值。您将保留对已销毁临时文件的引用。所以不幸的是我无法真正适应你的榜样......

答案 2 :(得分:0)

只是一个想法,这是怎么回事:

class A 
{
    std::shared_ptr<B> m_b;

public:
    A() : m_b(new B) {}
    A(B& b) : m_b(&b, [](B*){}) {}
};

另一方面,我反对存储您作为参考的任何内容,我觉得它根本不是您的用法。我也反对作为参考的成员,因为他们不允许任务操作员。