0

Compiler Tells me all the time about undefined reference to ChangeStateMachine() constructor. And I'm stuck at it for about an hour just staring at code and can't find any fail. Please help me find where i make mistake.

So thats my class file:

#pragma once
#include <iostream>

class ChangeStateMachine{
    private:
        int state;
        int newState;
    public:
        ChangeStateMachine();
        ChangeStateMachine(int state);

        void ChangeState(int newState);

        enum STATES{GAME, MENU, GAME_OVER};
};

Here I define ChangeStateMachine constructors:

#include "main.h"

ChangeStateMachine::ChangeStateMachine()
{   
    state = MENU;
    newState = -1;
}

ChangeStateMachine::ChangeStateMachine(int state)
{   
    ChangeStateMachine::state = state;
    newState = -1;
}

[...]

And call it in the main file:

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

//GLOBALS
ChangeStateMachine *SetState;

int main(void)
{   
    //PROJECT INIT
    SetState = new ChangeStateMachine();

[...]

The exact compiler error is:

../precompiled/main.cxx:13: undefined reference to `ChangeStateMachine::ChangeStateMachine()'

Thanks a lot for any response, Siery.

  • I recommend naming the header files relative to the class name. This will confuse people less, including yourself. – Thomas Matthews Jan 30 '16 at 01:07
  • You right. That was stupid idea to include change state to main.h. I change it now. –  Jan 30 '16 at 01:14

1 Answers1

0

Although the shown code in the question is not technically a Minimal, Complete, Verifiable Example, it's close enough to come up with the following answer:

So, I took your header file, and saved it as main.h, removing the compiler-specific pragma which, from the looks of it, is not needed no matter what it actually does:

#include <iostream>

class ChangeStateMachine{
    private:
        int state;
        int newState;
    public:
        ChangeStateMachine();
        ChangeStateMachine(int state);

        void ChangeState(int newState);

        enum STATES{GAME, MENU, GAME_OVER};
};

Then, I took the the two code snippets you posted, and combined them together into a single main.cpp file, whose actual, complete contents are:

#include "main.h"

ChangeStateMachine::ChangeStateMachine()
{   
    state = MENU;
    newState = -1;
}

ChangeStateMachine::ChangeStateMachine(int state)
{   
    ChangeStateMachine::state = state;
    newState = -1;
}

ChangeStateMachine *SetState;

int main(void)
{   
    //PROJECT INIT
    SetState = new ChangeStateMachine();
}

I'm sure there's no dispute that this actually reproduces the situation described in the question. It makes no difference whether the C++ code is broken down into one or two translation units, as long as everything is linked together. I don't see any detail that was missed.

And, finally, I was able to successfully compile and link the sample code, using gcc 5.3.1:

$ g++ -o main main.cpp
$ 

There were no linking errors. From this, and based on all evidence given, I therefore conclude that there is absolutely nothing wrong with the given C++ code. The problem must lie in your compiler's configuration, and/or how you're actually building your code. But, as far as C++, the language, goes, there is no issue here.

Sam Varshavchik
  • 114,536
  • 5
  • 94
  • 148
  • 1
    '#pragma once' do the same as '#ifndef ... #define ... #endif' will do just is shorter and less collisional :). I change the header file name as Thomas Matthews propose and now it compiles. Weird, looks like even compiler get confused by my name convention. –  Jan 30 '16 at 01:41