0

I am working on a project involving mathematical vectors in three-dimensional space (not to be confused with the vector collection type). I have a class Vector defined in Vector.cpp and declared in Vector.h. My directory structure is as follows:

Directory structure of project Vectors

When I attempt to build the project, I get an LNK2019 unresolved external symbol error. As far as I can tell, all three of my files are on the build path.

In Vector.cpp:

class Vector
{
private:
    double xComponent;
    double yComponent;
    double zComponent;
public:
    Vector(double x, double y, double z) : xComponent(x), yComponent(y), zComponent(z) {}

    double dotProduct(const Vector& other) const
    {
        return xComponent * other.xComponent + yComponent * other.yComponent + zComponent * other.zComponent;
    }
}

In Vector.h:

#ifndef VECTOR_H
#define VECTOR_H
class Vector
{
public:
    Vector(double x, double y, double z);
    double dotProduct(const Vector& other) const;
}
#endif

In Vectors.cpp:

#include "Vector.h"
#include <iostream>

using std::cout;
using std::endl;

int main()
{
    Vector foo = Vector(3, 4, -7);
    Vector bar = Vector(1.2, -3.6, 11);
    cout << foo.dotProduct(bar) << endl;
    return 0;
}

foo.dotProduct(bar) is the only place where a linker error occurs (no error occurs on the constructor). I have tried some of the other non-constructor methods of Vector and they also caused a linker error. Why does the constructor work but not any of the others?

This is the output from attempting to build the project:

1>------ Build started: Project: Vectors, Configuration: Debug Win32 ------
1>Vectors.obj : error LNK2019: unresolved external symbol "public: double __thiscall Vector::dotProduct(class Vector const &)const " (?dotProduct@Vector@@QBENABV1@@Z) referenced in function _main
1>C:\Users\John\Documents\Visual Studio 2017\Projects\Vectors\Debug\Vectors.exe : fatal error LNK1120: 1 unresolved externals
1>Done building project "Vectors.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
train1855
  • 300
  • 2
  • 5
  • 14
  • Vector should be declared in one file, not both. –  Oct 26 '17 at 21:57
  • @NeilButterworth I'm not quite sure I understand what you mean. Don't I need to have it forward-declared in the header file so that it can be used in `Vectors.cpp`? – train1855 Oct 26 '17 at 21:59
  • nope - vector.cpp should just have method bodies. Also please include the actual error text – pm100 Oct 26 '17 at 22:03
  • No. You have it declared in both the .h and the .cpp file. Please consult a C++ textbook on this. –  Oct 26 '17 at 22:04
  • and have not correctly included the method body - hence the link error – pm100 Oct 26 '17 at 22:06
  • This is expected behavior if you double declare. – Nick Oct 26 '17 at 22:09

1 Answers1

2

You defined the class twice. Once in header, once in the .cpp file.

Leave only function definitions in the .cpp file:

#include "Vector.h"

Vector::Vector(double x, double y, double z) : xComponent(x), yComponent(y), zComponent(z) 
{
}

double Vector::dotProduct(const Vector& other) const
{
    return xComponent * other.xComponent + yComponent * other.yComponent + zComponent * other.zComponent;
}

Every time you write class SomeClass {};, you define a symbol. There can be only one symbol with a given name defined in a namespace.

Please read up more on declarations and definitions. You can start here.

ivanmoskalev
  • 2,004
  • 1
  • 16
  • 25
  • 1
    Thanks. The C++ book I learned from assumed all the code was being written in a single file, hence my confusion. – train1855 Oct 29 '17 at 23:57