I have tried using pure virtual methods along with testing others answers on similar issues, but everything has continued to result in the same problem.
So I have this class Shape that acts as an interface declaring the virtual void Draw() method.
This function is later overridden in three other classes for primitive shapes, and called from a class called GameObject, which calls a method Draw() in WireframeImage and in it's turn calls one of these primitive shape classes.
When compiling I am presented with the following errors:
Error: LNK2001 unresolved external symbol "public: virtual void __thiscall Shape::Draw(class olc::PixelGameEngine,int,int,float,int,int,int)" (?Draw@Shape@@UAEXVPixelGameEngine@olc@@HHMHHH@Z)
File: GameObject.obj
Error: LNK2001 unresolved external symbol "public: virtual void __thiscall Shape::Draw(class olc::PixelGameEngine,int,int,float,int,int,int)" (?Draw@Shape@@UAEXVPixelGameEngine@olc@@HHMHHH@Z)
File: Shapes.obj
Error: LNK2001 unresolved external symbol "public: virtual void __thiscall Shape::Draw(class olc::PixelGameEngine,int,int,float,int,int,int)" (?Draw@Shape@@UAEXVPixelGameEngine@olc@@HHMHHH@Z)
File: WireframeImage.obj
Error: LNK1120 1 unresolved externals
Here's my code:
Shapes.h
#pragma once
#ifndef CLASS_SHAPES
#define CLASS_SHAPES
#include "olcPixelGameEngine.h"
class Shape
{
public:
    virtual void Draw(
        olc::PixelGameEngine engine,
        int originX,
        int originY,
        float scale,
        int rotation,
        int offsetX,
        int offsetY
    );
    olc::Pixel Color = olc::WHITE;
};
// Derived Shapes
class Line: public Shape {
private:
    Point P1, P2;
   public:
        Line();
        Line(Point, Point, olc::Pixel);
        void Draw(olc::PixelGameEngine engine, int originX, int originY, float scale, int rotation, int offsetX, int offsetY) override;
};
class Triangle: public Shape {
private:
    Line L1, L2, L3;
   public:
        Triangle();
        Triangle(Point, Point, Point, olc::Pixel);
        void Draw(olc::PixelGameEngine engine, int originX, int originY, float scale, int rotation, int offsetX, int offsetY) override;
};
class Rectangle: public Shape {
private:
    Line L1, L2, L3, L4;
   public:
        Rectangle();
        Rectangle(Point, Point, Point, Point, olc::Pixel);
        void Draw(olc::PixelGameEngine engine, int originX, int originY, float scale, int rotation, int offsetX, int offsetY) override;
};
#endif // !CLASS_SHAPES
Shapes.cpp
#include "Shapes.h"
Line::Line() { }
Line::Line(Point p1, Point p2, olc::Pixel color = olc::WHITE) {
    P1 = p1;
    P2 = p2;
    Color = color;
}
void Line::Draw(olc::PixelGameEngine engine, int originX, int originY, float scale, int rotation, int offsetX, int offsetY) {
    engine.DrawLine(P1.X, P1.Y, P2.X, P2.Y, Color);
}
Triangle::Triangle() { }
Triangle::Triangle(Point p1, Point p2, Point p3, olc::Pixel color = olc::WHITE) {
    L1 = {p1, p2, color};
    L2 = {p2, p3, color};
    L3 = {p3, p1, color};
    Color = color;
}
void Triangle::Draw(olc::PixelGameEngine engine, int originX, int originY, float scale, int rotation, int offsetX, int offsetY) {
    L1.Draw(engine, originX, originY, scale, rotation, offsetX, offsetY);
    L2.Draw(engine, originX, originY, scale, rotation, offsetX, offsetY);
    L3.Draw(engine, originX, originY, scale, rotation, offsetX, offsetY);
}
Rectangle::Rectangle() { }
Rectangle::Rectangle(Point p1, Point p2, Point p3, Point p4, olc::Pixel color = olc::WHITE) {
    L1 = {p1, p2, color};
    L2 = {p2, p3, color};
    L3 = {p3, p4, color};
    L4 = {p4, p1, color};
    Color = color;
}
void Rectangle::Draw(olc::PixelGameEngine engine, int originX, int originY, float scale, int rotation, int offsetX, int offsetY) {
    L1.Draw(engine, originX, originY, scale, rotation, offsetX, offsetY);
    L2.Draw(engine, originX, originY, scale, rotation, offsetX, offsetY);
    L3.Draw(engine, originX, originY, scale, rotation, offsetX, offsetY);
    L4.Draw(engine, originX, originY, scale, rotation, offsetX, offsetY);
}
WireframeImage.h
#pragma once
#ifndef CLASS_WIREFRAMEIMAGE
#define CLASS_WIREFRAMEIMAGE
#include <iostream>
#include "Shapes.h"
#include "SymmetryMode.h"
class WireframeImage
{
private:
    std::vector<Triangle>   _shapes;
    SymmetryMode        _symmetryMode;
public:
    WireframeImage();
    WireframeImage(std::string file);
    void Load(std::string file);
    void Draw(olc::PixelGameEngine engine, int x, int y, float scale, int rotation, int offsetX, int offsetY);
};
#endif // !CLASS_WIREFRAMEIMAGE
WireframeImage.cpp
#include "WireframeImage.h"
#include "Shapes.h"
#include <string>
#include <iostream>
WireframeImage::WireframeImage() { }
WireframeImage::WireframeImage(std::string file) {
    Load(file);
}
void WireframeImage::Load(std::string file) {
    // Code ...
}
void WireframeImage::Draw(olc::PixelGameEngine engine, int originX, int originY, float scale, int rotation, int offsetX, int offsetY) {
    for(Shape s : _shapes) {
        s.Draw(engine, originX, originY, scale, rotation, offsetX, offsetY);
    }
}
GameObject.h
#include "GameObject.h"
GameObject::GameObject() { }
GameObject::GameObject(olc::PixelGameEngine engine, WireframeImage sprite, int x, int y) {
    _engine = engine;
    Sprite = sprite;
    X = x;
    Y = y;
    Rotation = 0;
}
void GameObject::Draw() {
    this->Sprite.Draw(this->_engine, this->_engine.ScreenWidth()/2, this->_engine.ScreenHeight()/2, Scale, Rotation, X, Y);
}
I'm using Visual Studio 2017 if that's to any help.
