Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Undefined reference to class constructor, including .cpp file fixes

The problem I am having is that, when I call a constructor for a class I have created I get the following error.

main.cpp:20: undefined reference to `StaticObject::StaticObject(Graphics*, sf::String,
sf::Vector2)'

This problem can be 'fixed' adding an include for the .cpp file in main.cpp like so.

... #include "GameObjects/StaticObject.cpp" ... 

Although this solves the problem, this seems like a poor solution and goes against what I have been previously told. Is there any other way to solve this problem? I'm using Netbeans 7.3 with g++ to code/compile this program. Below is the relevant code.

main.cpp

...  #include <SFML/Graphics.hpp> #include "Graphics/Graphics.hpp" #include "GameObjects/StaticObject.hpp"  int main(int argc, char** argv) {      //SETUP     Graphics graphics;      background = new StaticObject(&graphics, "Data/Images/BackgroundPlaceholder.png",  sf::Vector2f(0,0));  ... 

main.hpp

...  #include <SFML/Graphics.hpp> #include "GameObjects/StaticObject.hpp"  ...  // Objects StaticObject *background; ... 

StaticObject.hpp

#include <SFML/Graphics.hpp> #include "../Graphics/Graphics.hpp"  class StaticObject{ public:     StaticObject();     StaticObject(Graphics *_graphics, sf::String texture_filename, sf::Vector2f _position);     StaticObject(const StaticObject& orig);     virtual ~StaticObject(); private:     // The sprite stores the position     sf::Sprite *sprite;     sf::Texture *texture; }; 

StaticObject.cpp

#include "StaticObject.hpp" #include <SFML/Graphics.hpp> #include "../Graphics/Graphics.hpp"  StaticObject::StaticObject(){     }  StaticObject::StaticObject(Graphics *_graphics, sf::String texture_filename, sf::Vector2f _position) {     sprite = _graphics->AddSprite(texture_filename);     sprite->setPosition(_position); }  StaticObject::StaticObject(const StaticObject& orig) { }  StaticObject::~StaticObject() { } 

If I add the following line to main.cpp, the error disappears.

#include "GameObject/StaticObject.cpp" 

Can anyone please explain:

  1. Why this fixes the problem?

  2. Why the .cpp was not implicitly included through including the .hpp file?

  3. Is there a better way of doing this?

like image 589
OMGtechy Avatar asked Mar 22 '13 20:03

OMGtechy


People also ask

How do you fix a undefined reference in C++?

You can fix undefined reference in C++ by investigating the linker error messages and then providing the missing definition for the given symbols. Note that not all linker errors are undefined references, and the same programmer error does not cause all undefined reference errors.

Can you make a constructor private in CPP if not what error will you get?

Yes, a constructor can be private. And you can call it with member functions (static or non) or friend functions. For possible use cases, see the Factory Pattern, or the Named Constructor Idiom. I would add the classical way of making a singleton.

What is constructor C++?

A constructor is a member function with the same name as its class. For example: class X { public: X(); // constructor for class X }; Constructors are used to create, and can initialize, objects of their class type.

What does undefined reference to main mean in C++?

Undefined reference to main() means that your program lacks a main() function, which is mandatory for all C++ programs.


1 Answers

The undefined reference error indicates that the definition of a function/method (i.e constructor here) was not found by the linker.

StaticObject::StaticObject(Graphics*, sf::String,    sf::Vector2<float>) 

And the reason that adding the following line:

#include "GameObject/StaticObject.cpp" 

fixes the issue, is it brings in the implementation as part of the main.cpp whereas your actual implementation is in StaticObject.cpp. This is an incorrect way to fix this problem.

I haven't used Netbeans much, but there should be an option to add all the .cpp files into a single project, so that Netbeans takes care of linking all the .o files into a single executable.

If StaticObject.cpp is built into a library of its own (I highly doubt that is the case here), then you might have to specify the path to the location of this library, so that the linker can find the implementation.

This is what ideally happens when you build your program:

Compile: StaticObject.cpp -> StaticObject.o Compile: main.cpp -> main.o Link: StaticObject.o, main.o -> main_program 

Although there are ways in gcc/g++ to skip all the intermediate .o file generations and directly generate the main_program, if you specify all the source files (and any libraries) in the same command line.

like image 98
Tuxdude Avatar answered Oct 08 '22 03:10

Tuxdude