0

I get Linker errors in the following example if I keep the PointFactory member functions as non-static.

#define _USE_MATH_DEFINES
#include <cmath>
#include <iostream>

class Point {
  private:
    Point(const double x, const double y) :
    x(x), y(y) {}

    class PointFactory {
      public:
        static Point NewCartesian(double x, double y) {
          return {x, y};
        }

        static Point NewPolar(double r, double theta) {
          return {r*cos(theta), r*sin(theta)};
        }
    };

  public:
    double x, y;

    // Needs to be friend coz stream object requires access to member variables
    friend std::ostream& operator<<(std::ostream& os, Point const& obj) {
      return os << "x: " << obj.x << " y: " << obj.y;
    }
    
    static PointFactory Factory;
};

int main() {
  auto pt = Point::Factory.NewPolar(5, M_PI_4);
  std::cout << pt << std::endl; 
  getchar();
  return 0;
}

Why do I need PointFactory members to be static? What is the reasoning behind this?

1 Answers1

0

Your linker error is caused by the fact that the variable Factory is declared in class Point but not defined anywhere.

Since class PointFactory is private within Point, the easiest fix is to change this:

static Point::PointFactory Factory;

to this:

inline static Point::PointFactory Factory;

This both declares and defines the variable all in one go, at the cost of requiring C++17.

Live demo

Paul Sanders
  • 24,133
  • 4
  • 26
  • 48
  • Thanks, this works and I understand this. I'm looking for reasoning behind how by defining member functions as static overcomes this issue? – Sourab Sharma Oct 17 '20 at 15:20
  • When you do that, the value of `Factory` is never used, so (it would seem) it needn't be defined, – Paul Sanders Oct 17 '20 at 18:54