【问题标题】:C++ facade avoiding copies避免复制的 C++ 外观
【发布时间】:2014-01-03 20:27:35
【问题描述】:

考虑以下简化的外观模式:

  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. 是否有(安全)方法来防止复制 传递的对象?

【问题讨论】:

  • 1.它可能会内联它。

标签: c++ copy facade


【解决方案1】:
  1. 在某些平台 (gcc/clang) 上,您可以强制使用属性 always_inline 进行内联,或者在函数未内联时发出警告。
  2. 不,如果你不想复制,你需要在别处保证对象的生命周期。如果您认为这不安全,请不要这样做。你可以做的是移动一个对象。这可以避免副本和生命周期问题,但您的编译器可能无法实现。

例如:

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

【讨论】:

    【解决方案2】:

    1- 是的,编译器最有可能内联函数[这取决于编译器)。

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

    注意:这个例子不是门面!

    【讨论】:

    • 你说得对,它也是一个适配器,但我一直认为外观是该模式的更“一般”描述(即抽象意图) - 不是这样吗?
    猜你喜欢
    • 1970-01-01
    • 2016-12-26
    • 2015-05-03
    • 2011-12-28
    • 1970-01-01
    • 2013-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多