Search code examples
c++heap-memoryunique-ptrprivate-constructornamed-constructor

How to return a class instance on the heap, when the relevant ctor is private?


Suppose I have this struct

struct MyStruct {

  static MyStruct Create(int x) {
    return { x*2, x>3 };
  }

  MyStruct(const MyStruct& c) = delete;  // no copy c'tor

private:
  MyStruct(int a_, bool b_) : a(a_), b(b_) {}  // private c'tor -- can't use new

  const int a;
  const bool b;
};

Edit: I deleted the copy constructor. This is simplified example of some classes I have in my codebase where they don't have copy c'tors.

I can get an instance on the stack like so:

int main() {
  auto foo = MyStruct::Create(2);
  return 0;
}

But suppose I need a pointer instead (or unique_ptr is fine), and I can't change the implementation of MyStruct, how can I do that?


Solution

  • You could wrap MyStruct in another class, which has a MyStruct member. Here's a minimal version of that:

    class Wrapper {
    public:
        MyStruct ms;
        Wrapper(int x) : ms(MyStruct::Create(x)) { }
    };
    

    which you can use like so:

    int main() {
      MyStruct::Create(2);
      std::make_unique<Wrapper>(2);
    }
    

    This code will not trigger any copies nor moves - because of copy elision (see: What are copy elision and return value optimization?).

    You can then add any other constructors and methods you like to such a wrapper, possibly forwarding some of the method calls to the ms member. Some might choose to make ms protected or private.