C ++外观避免副本

时间:2013-12-16 12:33:34

标签: c++ copy facade

考虑以下简化的立面图案:

  class Foo {
  public:
    int times;

    int eval(const int val) { return val*times; }
  };

  class Bar {
    Foo foo;
  public:
    Bar(const Foo& f) : foo(f) {}

    double eval(const double val) { return val * foo.times; }
  };

显然, Bar 的实例只需要评估 Foo的eval()方法的特殊(即双值)解释。除了 foo 之外,Bar不会有任何其他成员转发给。

出于安全考虑,我没有在Bar内部使用const引用或pointer(我还不知道Bar实例是否可能会从stack中逃脱框架,所以资源管理很重要)。

我的问题有两个方面:

  1. C++ 编译器可能会检测到Bar只是一个外观和 “内联”会员访问?
  2. 是否有(安全)方法来防止复制 传递的对象?

2 个答案:

答案 0 :(得分:2)

  1. 在某些平台(gcc / clang)上,您可以强制使用属性always_inline进行内联,或者如果函数没有内联则发出警告。
  2. 不,如果您不想复制,则需要保证对象的使用寿命。如果您认为这是不安全的,请不要这样做。你能做的就是移动一个物体。这可以避免副本和生命周期问题,但可能无法使用您的编译器。
  3. 例如:

     struct Bar {
       // Only accept rvalues of Foo
       explicit Bar(Foo&& f) : f(std::move(f)) {}
       Foo f;
     };
    

答案 1 :(得分:1)

1-是的,编译器将最可能内联函数[它取决于编译器]。

2-始终坚持RAII。在C ++ 3中,Foo对象foo应该是成员变量(如您所做)或托管指针(在复制构造函数和赋值运算符中复制,在析构函数中删除)。在C ++ 11中,您可以使用正确的值引用。

注意:此示例不是外观!