I'm trying to separate class definitions and implementations into different files. But I keep getting the following compiling error message:
undefined symbols for architecture x86_64:
  "PointArray::print()", referenced from:
      _main in Main-8fa367.o
  "PointArray::insert(int, Point const&)", referenced from:
      _main in Main-8fa367.o
  "PointArray::remove(int)", referenced from:
      _main in Main-8fa367.o
  "PointArray::push_back(Point const&)", referenced from:
      _main in Main-8fa367.o
  "PointArray::PointArray(Point const*, int)", referenced from:
      _main in Main-8fa367.o
  "PointArray::PointArray(PointArray const&)", referenced from:
      _main in Main-8fa367.o
  "Point::Point(Point&)", referenced from:
      _main in Main-8fa367.o
  "PointArray::get(int) const", referenced from:
      printPointArray(PointArray const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >) in Main-8fa367.o
  "Point::getX() const", referenced from:
      printPointArray(PointArray const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >) in Main-8fa367.o
  "Point::getY() const", referenced from:
      printPointArray(PointArray const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >) 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)
**I'm using the CodeRunner app on my Mac. The following code files are placed under the same directory.
This is the header file, "geometry.h"
#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 &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 &pArray);
    ~PointArray() { delete[] pointArray; } // delete or delete[] ???
    void push_back(const Point &p);
    void insert(const int position, const Point &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& pArray);
    ~Polygon();
    virtual double area();
    static int getNumPolygons() { return numOfPolygons; }
    int getNumSides() { return pointArray.getSize(); }
    const PointArray* getPoints() { return &pointArray; }
};
class Rectangle : public Polygon {
    public:
    Rectangle(const Point& p1, const Point& p2);
    Rectangle(int a, int b, int c, int d);
};
#endif
This is the class definition file, "geometry.cpp"
#include <iostream>
#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 &p) { setX(p.getX()); setY(p.getY()); }
PointArray::PointArray() {
    pointArray = new Point[0];
    size = 0;
}
PointArray::PointArray(const Point points[], const int size) {
    this->size = size; // ??? why -> ?
    pointArray = new Point[size];
    for (int i = 0; i < size; ++i) { pointArray[i] = points[i]; }
}
PointArray::PointArray(const PointArray &pArray) {
    size = pArray.getSize();
    pointArray = new Point[size];
    for (int i = 0; i < 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 < n; ++i) { tmp[i] = pointArray[i]; } 
    pointArray = new Point[n];
    for (int i = 0; i < n; ++i) { pointArray[i] = tmp[i]; }
    delete[] tmp;
}
void PointArray::push_back(const Point &p) {
    resize(size+1);
    pointArray[size-1] = p;
}
void PointArray::insert(const int position, const Point &p) {
    resize(size+1);
    for (int i = size-2; i > position; --i) { pointArray[i+1] = pointArray[i]; }
    pointArray[position] = p;
}
void PointArray::remove(const int position) {
    for (int i = position; i < size-1; ++i) { pointArray[i] = pointArray[i+1]; }
    resize(size-1);
}
void PointArray::clear() {
    pointArray = new Point[0];
    size = 0;
}
void PointArray::print() {
    cout<<"PointArray["<<size<<"]:\t\t";
    for (int i = 0; i < size; ++i) {
        cout<<pointArray[i].getX()<<" "<<pointArray[i].getY()<<";\t";
    }
    cout<<endl;
}
Point* PointArray::get(const int position) {
    if (size > 0 && position < size) { return &pointArray[position]; }
    else { return NULL; }
}
const Point* PointArray::get(const int position) const {
    if (size > 0 && position < size) { return &pointArray[position]; }
    else { return NULL; }
}
Polygon::Polygon(const PointArray& pArray) {
    pointArray = pArray;
    numOfPolygons = pArray.getSize();
}
Polygon::~Polygon() {
    pointArray.clear();
    numOfPolygons = 0;
}
This is the main implementation file, "Main.cpp"
    #include <iostream>
    #include "geometry.h"
    using namespace std;
    void printPointArray(const PointArray &pArray, string arrayName = "noName") {
        cout<<"PointArray "<<arrayName<<"["<<pArray.getSize()<<"]:\t";
        for (int i = 0; i < pArray.getSize(); ++i) {
            cout<<pArray.get(i)->getX()<<" "<<pArray.get(i)->getY()<<";\t";
        }
        cout<<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;
    }
