Solved

C++ linker unresolved symbols (splitting into *.h and *.cpp files)

Posted on 2013-11-12
1
317 Views
Last Modified: 2013-11-12
This sample program worked fine when it was all in one file. when I tried to split it into *.h and *.cpp files I'm getting linker errors now.
Error   1       error LNK2001: unresolved external symbol "public: virtual void __thiscall BaseState::eventA(class Machine *)" (?eventA@BaseState@@UAEXPAVMachine@@@Z)  C:\Users\Public\0SBCS\VS\test\StatePattern3\StatePattern3\BaseState.obj StatePattern3
BaseState.h
#pragma once

class Machine;  //forward declaration

class BaseState
{
public:
  BaseState(void);
  public:
    virtual void eventA(Machine *m);
    virtual void eventB(Machine *m);

};

Open in new window

BaseState.cpp
#include "StdAfx.h"
#include <iostream>
#include "BaseState.h"
using namespace std;

BaseState::BaseState(void)
{
}

void eventA(Machine *m)
{
    cout << "\nEventA - do nothing";
}
void eventB(Machine *m)
{
    cout << "\nEventB - do nothing";
}

Open in new window

StateONE.h
#pragma once
#include "BaseState.h"

class Machine;

class StateONE : public BaseState
{
public:
    StateONE(void);
    void eventB(Machine *m);
};

Open in new window

StateONE.cpp
#include "StdAfx.h"
#include <iostream>
#include "StateONE.h"
#include "Machine.h"
using namespace std;

StateONE::StateONE(void)
{
    cout << "\n   StateONE-ctor ";
};

void StateONE::eventB(Machine *m)
{
    cout << "\n   In StateONE, handing eventB, switching to stateTwo";
    m->setCurrent(&m->stateTwo);
}

Open in new window

StateTWO.h
#pragma once
#include "BaseState.h"

class Machine;  //forward declaration

class StateTWO : public BaseState
{
public:
    StateTWO(void);
    void eventA(Machine *m);
};

Open in new window

StateTWO.cpp
#include "StdAfx.h"
#include <iostream>
#include "StateTWO.h"
#include "Machine.h"
using namespace std;

StateTWO::StateTWO(void)
{
        cout << "\n   StateTWO-ctor ";
}

void StateTWO::eventA(Machine *m)
{
    cout << "\n   In StateTWO, handling eventA. Switching to stateOn";
    m->setCurrent(&m->stateOne);
}

Open in new window

Machine.h
#pragma once
#include "BaseState.h"
#include "StateONE.h"
#include "StateTWO.h"

class Machine
{
private:
    class BaseState *currentState;
public:
    Machine(void);
    StateONE stateOne;
    StateTWO stateTwo;
    void setCurrent(BaseState *s);
    void HandleEventA();
    void HandleEventB();
};

Open in new window

Machine.cpp
#include "StdAfx.h"
#include <iostream>
#include "Machine.h"
using namespace std;


Machine::Machine(void)
{
  cout << "\nMachine Constructor";
  currentState = &stateTwo;
}

void Machine::HandleEventA()
{
  currentState->eventA(this);
}

void Machine::HandleEventB()
{
  currentState->eventB(this);
}

void Machine::setCurrent(BaseState *s)
{
    currentState = s;
}

Open in new window

Main
#include "stdafx.h"
#include "Machine.h"

int _tmain(int argc, _TCHAR* argv[])
{
  Machine fsm;

  fsm.HandleEventB();
  fsm.HandleEventA();
  fsm.HandleEventB();

	return 0;
}

Open in new window

0
Comment
Question by:deleyd
1 Comment
 
LVL 86

Accepted Solution

by:
jkr earned 500 total points
Comment Utility
You are missin gthe class' scope with the implementations in BaseState.cpp - that should be

#include "StdAfx.h"
#include <iostream>
#include "BaseState.h"
using namespace std;

BaseState::BaseState(void)
{
}

void BaseState::eventA(Machine *m) // 'BaseState::' was missing
{
    cout << "\nEventA - do nothing";
}
void BaseState::eventB(Machine *m) // 'BaseState::' was missing
{
    cout << "\nEventB - do nothing";
}

Open in new window

0

Featured Post

Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

Join & Write a Comment

IntroductionThis article is the second in a three part article series on the Visual Studio 2008 Debugger.  It provides tips in setting and using breakpoints. If not familiar with this debugger, you can find a basic introduction in the EE article loc…
Introduction This article is a continuation of the C/C++ Visual Studio Express debugger series. Part 1 provided a quick start guide in using the debugger. Part 2 focused on additional topics in breakpoints. As your assignments become a little more …
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now