Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 512
mpen Avatar asked Mar 02 '23 10:03

mpen


2 Answers

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.

like image 196
einpoklum Avatar answered Apr 08 '23 22:04

einpoklum


Is this what you're looking for?

auto baz  = std::make_unique<MyStruct>( MyStruct::Create(2) );  // unique pointer
like image 26
Jojo Avatar answered Apr 08 '23 20:04

Jojo