简体   繁体   English

C ++外观避免复制

[英]C++ facade avoiding copies

Consider the following, simplified facade pattern: 考虑以下简化的外观模式:

  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; }
  };

Obviously, an instance of Bar is only required to evaluate a special (ie double-valued) interpretation of Foo's eval() method. 显然,只需要Bar的实例即可评估Foo的eval()方法的特殊(即双值)解释。 A Bar won't have any other members except the foo it forwards to. 吧台除了转发给它的foo外,没有其他成员。

For safety reasons I have not used a const reference or a pointer inside Bar (I just don't know yet if at some point a Bar instance might escape from a stack frame, so resource management is important). 出于安全原因,我没有在Bar内部使用const引用或pointer (我只是不知道Bar实例是否可能在某个时刻从stack帧中逸出,因此资源管理很重要)。

My question here is two fold: 我的问题有两个:

  1. Can the C++ compiler possibly detect that Bar is merely a facade and " inline " the member access? C++ 编译器是否可以检测到Bar只是一个外观并“ 内联 ”成员访问?
  2. Is there a (safe) way to prevent copying of the passed object? 是否有(安全)方法来防止复制传递的对象?
  1. On some platforms (gcc/clang) you can force inlining with the attribute always_inline or emit warnings should a function not be inlined. 在某些平台(gcc / clang)上,您可以强制使用always_inline属性进行内联,或者在未内联函数的情况下发出警告。
  2. No, if you don't want to copy, you need to guarantee the life-time of the object elsewhere. 不,如果您不想复制,则需要保证对象在其他地方的生命周期。 If you consider this to be unsafe, don't do it. 如果您认为这不安全,请不要这样做。 What you can do is move an object. 您可以做的就是移动一个对象。 This avoids copies and life-time issues, but might not be possible with your compiler. 这样可以避免复制和使用期限问题,但是对于您的编译器来说可能是不可能的。

For example: 例如:

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

1- Yes, the compiler will most probably inline the function [It depends on compiler). 1-是的,编译器很可能会内联函数[取决于编译器]。

2- Always stick to RAII . 2-始终坚持RAII In C++3, Foo object foo shall be either member variable (as you did), or managed pointer (copied at copy constructor and assignment operator and deleted at destructor). 在C ++ 3中, Foo对象foo应该是成员变量(如您所做的那样)或托管指针(在复制构造函数和赋值运算符中复制,并在析构函数中删除)。 In C++11 you can use right value reference. 在C ++ 11中,您可以使用正确的值引用。

NOTE: This example is not a facade! 注意:此示例不是立面!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM