c++ multiple definition error for every constructor, method, and operator overload [duplicate]

StackOverflow https://stackoverflow.com/questions/14953166

  •  10-03-2022
  •  | 
  •  

Question

I realize that there are a lot of "multiple definition" questions out here already, but I've spent the past 2 hours looking for an explanation and haven't found one. So sorry if this is a duplicate.

Right now I have 2 classes: Array.h and Vector.h. Neither has any global variables, and neither is dependent on the other (i.e. Array doesn't use Vector and Vector doesn't use Array). The implementations are in the .h files.

Here's my Main.cpp:

#include <iostream>
#include "Array.h"
#include "Vector.h"
using namespace std;

int main() {
    cout << "Done" << endl;

    return 0;
}

...and everything runs fine. However, when I create another .cpp file with only #include statements...

DataReader.cpp

#include "Array.h"
#include "Vector.h"

...then everything blows up and I get a whole slew of errors for every method, constructor, and operator overload in Vector:

DataReader.o: In function `Vector':
C:\C++\Eclipse CDT\workspace\3D_Adaptive_FEM\Debug/..//Vector.h:49: multiple definition of `Vector::Vector()'
TestMain.o:C:\C++\Eclipse CDT\workspace\3D_Adaptive_FEM\Debug/..//Vector.h:49: first defined here
DataReader.o: In function `Vector':
C:\C++\Eclipse CDT\workspace\3D_Adaptive_FEM\Debug/..//Vector.h:53: multiple definition of `Vector::Vector(int const&, int const&, int const&)'
TestMain.o:C:\C++\Eclipse CDT\workspace\3D_Adaptive_FEM\Debug/..//Vector.h:53: first defined here
DataReader.o: In function `Vector':
C:\C++\Eclipse CDT\workspace\3D_Adaptive_FEM\Debug/..//Vector.h:56: multiple definition of `Vector::Vector(double const&, double const&, double const&)'
TestMain.o:C:\C++\Eclipse CDT\workspace\3D_Adaptive_FEM\Debug/..//Vector.h:56: first defined here
DataReader.o: In function `ZNK6Vector1xEv':
C:\C++\Eclipse CDT\workspace\3D_Adaptive_FEM\Debug/..//Vector.h:59: multiple definition of `Vector::x() const'
TestMain.o:C:\C++\Eclipse CDT\workspace\3D_Adaptive_FEM\Debug/..//Vector.h:59: first defined here

etc...

But if I just have #include "Array.h" in DataReader.cpp, then everything runs fine!

What can possibly be wrong with #include "Vector.h" that doesn't apply to #include "Array.h"?

Edit: Separating the implementations into .cpp files fixes the errors, but that doesn't explain why I have to do it for Vector and not Array.

Was it helpful?

Solution

I suspect you have out-of-line definitions of these functions in you header. E.g.

#ifndef VECTOR_H
#define VECTOR_H

class Vector
{
public:
    Vector(int x, int y, int z);
private:
    int m_x, m_y, m_z;
};

Vector::Vector(int x, int y, int z)
    : m_x(x), m_y(y), m_z(z)
{}

#endif

Since the definition of the constructor is not inline in the class definition, the compiler does not make it implicitly inline. Now, if you include the same file in multiple translation units (i.e. *.cpp files), the linker will produce exactly the error you see, because each of the *.cpp files will contain its own definition of the constructor without them being marked as inline functions.

The solution is easy, just put a inline in front of the constructor declaration:

class Vector
{
public:
    inline Vector(int x, int y, int z);
    // ...
};

// ...

Alternatively, if the function body is short, as is the case with the constructor shown above, directly inline the function definition into the class definition, as

class Vector
{
public:
    Vector(int x, int y, int z)
        : m_x(x), m_y(y), m_z(z)
    {}
    // ...
};

// ...
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top