c++c++11abseil

Implementing Factory Function with STL by Replicating Abseil Example


Trying to better understand Tip of the Week #42: Prefer Factory Functions to Initializer Methods by replicating the example using the standard template library. OP provides the example code:

// foo.h
class Foo {
 public:
  // Factory method: creates and returns a Foo.
  // May return null on failure.
  static std::unique_ptr<Foo> Create();

  // Foo is not copyable.
  Foo(const Foo&) = delete;
  Foo& operator=(const Foo&) = delete;

 private:
  // Clients can't invoke the constructor directly.
  Foo();
};

// foo.c
std::unique_ptr<Foo> Foo::Create() {
  // Note that since Foo's constructor is private, we have to use new.
  return absl::WrapUnique(new Foo());
}

When trying to replicate the example, I use a different approach in the foo.c section:

std::unique_ptr<Foo> Foo::Create() {
    // Attempt to create using std::unique_ptr instead of absl::WrapUnique
    return std::unique_ptr<Foo>(new Foo());
}

Compiling with the following commands results in a failed linker command

$ clang++  -g -Wall -std=c++11 -fsanitize=address foo.cc -o Foo

Undefined symbols for architecture arm64:
  "Foo::Foo()", referenced from:
      Foo::Create() in robots-cda3fd.o
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Thoughts about what I'm missing here? Thanks!


Solution

  • You still need to define Foo::Foo()

    1. In the header you can do Foo() = default, even in the private section
    2. In the cpp you can do Foo::Foo() = default or Foo::Foo() {}