-2

I see lots of examples of smart pointers declared within a main or a function, but so far, none that shows the syntax of a C++ class constructor that returns a smart pointer from the get go. If that's possible, can someone please illustrate proper syntax?

DarkSky
  • 47
  • 2
  • 5
    C++ constructors don't "return" anything. Can you clarify what you mean? You want an example of a constructor for the smart pointer class itself, or for a class that holds a smart pointer in its member data, or for a class that uses a smart pointer within its constructor to prepare member data but the smart pointer isn't a member? Or did you want to know about factory functions which are not actually constructors and do return values? – Ben Voigt Feb 01 '22 at 21:39
  • 2
    Constructors don't return anything. They build an instance of a class. – Paul Sanders Feb 01 '22 at 21:39

1 Answers1

0

You probably want to use a static class member factory function, and std::make_unique within it.

However, since std::make_unique is unable to be a friend of the class, it won't have access to the private constructor. Alas.

To work around that limitation, provide a private key that the factory function can pass to the std::make_unique for the public constructor class.

(Possibly this known limitation has been corrected in C++20 or C++23.)

If forcing the std::unique_ptr<Foo> use-case is not needed, then Foo can just have a public constructor, which allows a Foo object to be created any whichever way is the code using the Foo wants to do it.

#include <iostream>
#include <memory>
#include <string>
#include <utility>

class Foo {
    enum class Key { secret };
    std::string name;
public:
    Foo(Key, std::string name_) : name{std::move(name_)} { }
    static auto Make(std::string name_) -> std::unique_ptr<Foo> {
        return std::make_unique<Foo>(Key::secret, std::move(name_));
    }

    friend auto operator<<(std::ostream& out, Foo const& foo) -> std::ostream& {
        return out << "Foo \"" << foo.name << "\" was here.";
    }
};

int main() {
    auto bob = Foo::Make("Bob");
    std::cout << *bob << "\n";

    // Foo jeff{Foo::Key::secret, "Jeff"}; // Not allowed.
}
Eljay
  • 4,648
  • 3
  • 16
  • 27
  • 2
    "*However, since `std::make_unique` is unable to be a `friend` of the class, it won't have access to the private constructor. Alas.*" - duplicate of [How to make std::make_unique a friend of my class](https://stackoverflow.com/questions/33905030/) – Remy Lebeau Feb 01 '22 at 23:05