I can never seem to get these right, but I can't see any difference from other projects. When I try and compile I get linker errors, here are my pages:
ERROR
Deleting intermediate and output files for project 'Scripting', configuration 'Debug|Win32'
Compiling...
Implementations.cpp
main.cpp
Generating Code...
Linking...
main.obj : error LNK2019: unresolved external symbol "public: void __thiscall VirtualMachine::Execute(unsigned int)" (?Execute@VirtualMachine@@QAEXI@Z) referenced in function _main
C:\Documents and Settings\Nate\My Documents\Visual Studio 2005\Projects\Scripting\Debug\Scripting.exe : fatal error LNK1120: 1 unresolved externals
Build log was saved at "file://c:\Documents and Settings\Nate\My Documents\Visual Studio 2005\Projects\Scripting\Scripting\Debug\BuildLog.htm"
Scripting - 2 error(s), 0 warning(s)
========== Rebuild All: 0 succeeded, 1 failed, 0 skipped ==========
Declarations.h
#ifndef DECLARATIONS_H
#define DECLARATIONS_H
#include <vector>
enum opcode
{
op_talk,
op_end
};
// the basic instruction, currently just encapsulating code
class Instruction
{
private:
opcode _code;
//char* _data; // additional data, currently not used
public:
Instruction(opcode code) : _code(code) {}
opcode Code() const { return _code; }
};
// the basic script, currently just encapsulating an arrayed list of instructions
class Script
{
private:
std::vector<Instruction> _instrList;
public:
Script(const std::vector<Instruction>& instrList) : _instrList(instrList) {}
const Instruction* InstrPtr() const { return &_instrList[0]; }
};
// rudimentary virtual machine wiht methods inlined for convenience
class VirtualMachine
{
private: // useful abstractions
// pointers used as non-modifying dynamic references
typedef const Script* ScriptRef;
typedef const Instruction* InstrRef;
private: // data members
std::vector<Script> _scriptList;
ScriptRef _scriptPtr; // current script
InstrRef _instrPtr; // root instruction
InstrRef _instr; // current instruction
size_t _scriptCount; // track the loaded scripts
private: // utilities
size_t AddScript(const Script& script); // add script to list and retrieve id
void SelectScript(size_t index); // set current script by id
public:
VirtualMachine() : _scriptPtr(0), _instrPtr(0), _instr(0), _scriptCount(0) {}
// a very basic interface
inline void Execute(size_t scriptId);
size_t Load(const Script& script) { return AddScript(script); }
};
#endif
Implementations.cpp
#include "Declarations.h"
#include <iostream>
#include <cassert>
size_t VirtualMachine::AddScript(const Script& script)
{
_scriptList.push_back(script);
return _scriptCount++;
}
void VirtualMachine::SelectScript(size_t index)
{
assert(index < _scriptCount); // make sure the id is valid
_scriptPtr = &_scriptList[index];
_instrPtr = _scriptPtr->InstrPtr();
}
void VirtualMachine::Execute(size_t scriptId)
{
SelectScript(scriptId); // select our _instrPtr by scriptId
_instr = _instrPtr; // set out iterator to beginning
while(_instr)
{
switch(_instr->Code())
{
case op_talk:
std::cout << "I am talking." << std::endl;
++_instr; // iterate
break;
case op_end:
_instr = 0; // discontinue the loop
break;
}
}
}
main.cpp
#include "Declarations.h"
int main()
{
VirtualMachine vm;
// build the script
std::vector<Instruction> InstrList;
InstrList.push_back(Instruction(op_talk)); // talk twice
InstrList.push_back(Instruction(op_talk));
InstrList.push_back(Instruction(op_end)); // then end
Script script(InstrList);
// load the script and save the id
size_t scriptID = vm.Load(script);
// execute the script by its id
vm.Execute(scriptID);
}