C++: separation of class definitions and implementation, but keep getting compiling errors
<p>I'm trying to separate class definitions and implementations into different files. But I keep getting the following compiling error message:</p>

<pre><code>undefined symbols for architecture x86_64:
  "PointArray::print()", referenced from:
      _main in Main-8fa367.o
  "PointArray::insert(int, Point const&amp;)", referenced from:
      _main in Main-8fa367.o
  "PointArray::remove(int)", referenced from:
      _main in Main-8fa367.o
  "PointArray::push_back(Point const&amp;)", referenced from:
      _main in Main-8fa367.o
  "PointArray::PointArray(Point const*, int)", referenced from:
      _main in Main-8fa367.o
  "PointArray::PointArray(PointArray const&amp;)", referenced from:
      _main in Main-8fa367.o
  "Point::Point(Point&amp;)", referenced from:
      _main in Main-8fa367.o
  "PointArray::get(int) const", referenced from:
      printPointArray(PointArray const&amp;, std::__1::basic_string&lt;char, std::__1::char_traits&lt;char&gt;, std::__1::allocator&lt;char&gt; &gt;) in Main-8fa367.o
  "Point::getX() const", referenced from:
      printPointArray(PointArray const&amp;, std::__1::basic_string&lt;char, std::__1::char_traits&lt;char&gt;, std::__1::allocator&lt;char&gt; &gt;) in Main-8fa367.o
  "Point::getY() const", referenced from:
      printPointArray(PointArray const&amp;, std::__1::basic_string&lt;char, std::__1::char_traits&lt;char&gt;, std::__1::allocator&lt;char&gt; &gt;) in Main-8fa367.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
</code></pre>

<p>**I'm using the CodeRunner app on my Mac. The following code files are placed under the same directory.</p>

<p>This is the header file, "geometry.h"</p>

<pre><code>#ifndef GEOMETRY_H
#define GEOMETRY_H

using namespace std;

class Point {
    private:
    int x;
    int y;

    public:
    Point() { x = 0; y = 0; }
    Point(int a, int b) : x(a), y(b) {}
    Point(Point &amp;p);

    int getX() const;
    int getY() const;

    void setX(const int new_x);
    void setY(const int new_y);
};

class PointArray {
    private:
    Point *pointArray;
    int size;
    void resize(int n);

    public:
    PointArray();

    PointArray(const Point points[], const int size);

    PointArray(const PointArray &amp;pArray);



    ~PointArray() { delete[] pointArray; } // delete or delete[] ???

    void push_back(const Point &amp;p);

    void insert(const int position, const Point &amp;p);

    void remove(const int position);

    void clear();

    void print();

    const int getSize() const { return size; } // why double const???

    Point* getInternalArray() const { return pointArray; }

    Point* get(const int position);
    const Point* get(const int position) const;
};

class Polygon {
    protected:
    PointArray pointArray;
    static int numOfPolygons;

    public:
    Polygon(const Point points[], const int size) : pointArray(PointArray(points, size)) { numOfPolygons = size; }

    Polygon(const PointArray&amp; pArray);

    ~Polygon();

    virtual double area();
    static int getNumPolygons() { return numOfPolygons; }
    int getNumSides() { return pointArray.getSize(); }
    const PointArray* getPoints() { return &amp;pointArray; }
};

class Rectangle : public Polygon {
    public:
    Rectangle(const Point&amp; p1, const Point&amp; p2);
    Rectangle(int a, int b, int c, int d);

};

#endif
</code></pre>

<p>This is the class definition file, "geometry.cpp"</p>

<pre><code>#include &lt;iostream&gt;
#include "geometry.h"

using namespace std;

int Point::getX() const { return x; }

int Point::getY() const { return y; }

void Point::setX(const int new_x) { x = new_x; }

void Point::setY(const int new_y) { y = new_y; }

Point::Point(Point &amp;p) { setX(p.getX()); setY(p.getY()); }

PointArray::PointArray() {
    pointArray = new Point[0];
    size = 0;
}

PointArray::PointArray(const Point points[], const int size) {
    this-&gt;size = size; // ??? why -&gt; ?
    pointArray = new Point[size];
    for (int i = 0; i &lt; size; ++i) { pointArray[i] = points[i]; }
}

PointArray::PointArray(const PointArray &amp;pArray) {
    size = pArray.getSize();
    pointArray = new Point[size];
    for (int i = 0; i &lt; pArray.getSize(); ++i) {
        pointArray[i] = pArray.getInternalArray()[i];
    }
}

void PointArray::resize(int n) {
    size = n;   
    Point* tmp = new Point[n];  
    for (int i = 0; i &lt; n; ++i) { tmp[i] = pointArray[i]; } 
    pointArray = new Point[n];
    for (int i = 0; i &lt; n; ++i) { pointArray[i] = tmp[i]; }
    delete[] tmp;
}

void PointArray::push_back(const Point &amp;p) {
    resize(size+1);
    pointArray[size-1] = p;
}

void PointArray::insert(const int position, const Point &amp;p) {
    resize(size+1);
    for (int i = size-2; i &gt; position; --i) { pointArray[i+1] = pointArray[i]; }
    pointArray[position] = p;
}

void PointArray::remove(const int position) {
    for (int i = position; i &lt; size-1; ++i) { pointArray[i] = pointArray[i+1]; }
    resize(size-1);
}

void PointArray::clear() {
    pointArray = new Point[0];
    size = 0;
}

void PointArray::print() {
    cout&lt;&lt;"PointArray["&lt;&lt;size&lt;&lt;"]:\t\t";
    for (int i = 0; i &lt; size; ++i) {
        cout&lt;&lt;pointArray[i].getX()&lt;&lt;" "&lt;&lt;pointArray[i].getY()&lt;&lt;";\t";
    }
    cout&lt;&lt;endl;
}

Point* PointArray::get(const int position) {
    if (size &gt; 0 &amp;&amp; position &lt; size) { return &amp;pointArray[position]; }
    else { return NULL; }
}

const Point* PointArray::get(const int position) const {
    if (size &gt; 0 &amp;&amp; position &lt; size) { return &amp;pointArray[position]; }
    else { return NULL; }
}

Polygon::Polygon(const PointArray&amp; pArray) {
    pointArray = pArray;
    numOfPolygons = pArray.getSize();
}

Polygon::~Polygon() {
    pointArray.clear();
    numOfPolygons = 0;
}
</code></pre>

<p>This is the main implementation file, "Main.cpp"</p>

<pre><code>    #include &lt;iostream&gt;
    #include "geometry.h"

    using namespace std;

    void printPointArray(const PointArray &amp;pArray, string arrayName = "noName") {
        cout&lt;&lt;"PointArray "&lt;&lt;arrayName&lt;&lt;"["&lt;&lt;pArray.getSize()&lt;&lt;"]:\t";
        for (int i = 0; i &lt; pArray.getSize(); ++i) {
            cout&lt;&lt;pArray.get(i)-&gt;getX()&lt;&lt;" "&lt;&lt;pArray.get(i)-&gt;getY()&lt;&lt;";\t";
        }
        cout&lt;&lt;endl;
    }

    int main(int argc, char *argv[]) {
        Point p1 (3,5);
        Point p2 (14,14);
        Point p3 (100,30);

        Point *p = new Point(1,1);

        Point points[3] = {p1, p2, p3};

        PointArray pa (points, 3);
        PointArray pb = pa;
        const PointArray pc = pb;

        pb.insert(1, *p);
        pb.push_back(*p);
        pb.remove(2);
        //pb.clear();

        pa.print();

        printPointArray(pb, "pb");
        printPointArray(pc);

        return 0;
    }
</code></pre>