Reputation: 123
Whenever I compile something that #includes a user-defined class, I get these compilation errors that always look like: main.cpp: undefined reference to Complex::Complex(double, double)
I've reduced the problem to a set of three extremely bare files: main.cpp, and for example, Complex.h and Complex.cpp. I still get undefined reference errors. I'm developing in Code::Blocks on Windows but I get the same thing using g++ in Ubuntu. Why does this happen? I've tried building Complex.cpp before main.cpp in Code::Blocks, and I've tried g++ main.cpp Complex.cpp
as much as I've tried just g++ main.cpp
. Same errors every time.
/*======== main.cpp ========*/
#include "Complex.h"
int main()
{
Complex A(1.0, 1.0);
return 0;
}
/*======== Complex.h ========*/
#ifndef _COMPLEX_H
#define _COMPLEX_H
class Complex
{
public:
double x, y;
Complex(double real, double imag);
};
#endif
/*======== Complex.cpp ========*/
#include "Complex.h"
Complex::Complex(double real, double imag)
{
x = real;
y = imag;
}
ed: now I get different errors so I must be doing something completely wrong. Using the same code as above, I get:
main.cpp: in function 'int main()':
main.cpp:5:5: error: 'Complex' was not declared in this scope
main.cpp:5:13: error: expected ';' before 'A'
This is bizarre. Everything worked earlier when I had the class in a .cpp file, but that's "bad practice" so I moved my class definitions into .h files and kept the implementation in .cpp files, and now nothing works.
Upvotes: 7
Views: 17955
Reputation: 154015
While we are left in the dark whether this is the actual code (probably not as it works for several others), let's comment on the code itself a bit... (this won't have any effect on the linker error)
private
. There is rarely any need to make actual data member public
(sometimes it is reasonable to make non-function members public
, e.g. an event class where users can subscribe callbacks, but these typically behave like functions although they are technically objects).Initialization is best done in the member initializer list. That is, the constructor would look something like this:
Complex::Complex(double real, double image): x(real), y(imag) { }
Finally, to venture a few guesses what is going wrong with the actual code to cause the linking problem:
inline
. Obviously, this won't work unless the definition is visible where the constructor is used.Complex
somehow made it into an unnamed namespace and thus the definition happens to define a different class than the one seen by main.cpp.Upvotes: 1
Reputation: 225142
That's not a compilation error, it's a link error. You need to make sure to link all of your objects together. You can do that in a couple ways:
g++ main.cpp Complex.cpp
Should work fine (and does here when I tried with your example). You can also do it in steps:
g++ -c main.cpp
g++ -c Complex.cpp
g++ main.o Complex.o
Upvotes: 7