简体   繁体   中英

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. A Bar won't have any other members except the foo it forwards to.

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).

My question here is two fold:

  1. Can the C++ compiler possibly detect that Bar is merely a facade and " inline " the member access?
  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.
  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).

2- Always stick to 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). In C++11 you can use right value reference.

NOTE: This example is not a facade!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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