Search code examples
c++raii

How to guarantee only one construction of an object returned by value?


I'm trying to implement a class, say Foo, which follows RAII, and objects of the class are returned to the client by value, i.e.

class SomeClass {
public:
  class Foo {
    public:
      ~Foo() { /* follow raii */ }
    private:
      friend class SomeClass;
      Foo() { /* follow raii */ }
  };

  Foo getFoo() { return Foo(); }
};

My immediate question would be is there any way to be sure that only one object of type Foo is constructed when calling SomeClass::getFoo()? I would think that most compilers know only one object need be constructed, but I know this is not guaranteed in most cases. Is there a better approach I can take?

I've tried returning a boost::shared_ptr<Foo> and just allocating a Foo object when constructing the shared pointer, and this works nicely. However, it does not seem ideal, as it requires heap allocation and makes for a less-clean interface.

Thanks!

Clarification

Visual Studio 2005 compiler so I don't think R-val references and C++11 related features are available.


Solution

  • You've taken the best approach. The copy (or in fact move in C++11) will almost surely be elided by the compiler. In fact, even the copy from the return value to some object in the calling code will probably be elided too. So this will only call a single constructor:

    Foo foo = sc.getFoo();
    

    The rule that allows both of these copies (or moves) to be elided is:

    when a temporary class object that has not been bound to a reference (12.2) would be copied/moved to a class object with the same cv-unqualified type, the copy/move operation can be omitted by constructing the temporary object directly into the target of the omitted copy/move