I've been looking at a command design pattern to go in my portfolio, and have gotten a little stuck when implementing my own variation.
It started when I wanted to pass a vector of pointers (of command objects) to a player/actor class that would be able to access them as a queue. Prior to this I was accessing them directly through main, but I wanted the player to have a direct access to the queue.
I would really appreciate some help on this, specifically with making it work without much changes (so I learn how to fix this type of error), but don't mind other ideas and solutions in addition.
I'll describe what you're seeing and then let the code speak for itself.
5 files a main (source.cpp) and then the Player Object and the Attack (command) Object has 2 files each, a header and its subsequent cpp implementation.
I'm still learning more about implementing classes outside out their header and and have been learning a lot about what to do and what not to do, and what isn't necessary etc.
The FIRST real sticking error I came across was that the Player class wouldn't recognise the Vector of pointers-to-command objects named AttackCmd (the base class of the specific types of Attack, such as AtkNavy and Infantry etc.)
I played around with including and as far as it looks, I've fixed this and not have linker errors.
lastly I've tried to preview my question and use the Code tags etc but there seems to be an error so if this post works I will edit it as soon as it allows me
you will see I am getting 3 unresolved external symbol errors from main,
Severity Code Description Project File Line Suppression State
Error LNK2019 unresolved external symbol "public: __thiscall AtkInfantry::AtkInfantry(void)" (??0AtkInfantry@@QAE@XZ) referenced in function _main Command DP My version C:\Users\ryanb\source\repos\Command DP My version\Command DP My version\Source.obj 1
Severity Code Description Project File Line Suppression State
Error LNK2019 unresolved external symbol "public: __thiscall AtkNavy::AtkNavy(void)" (??0AtkNavy@@QAE@XZ) referenced in function _main Command DP My version C:\Users\ryanb\source\repos\Command DP My version\Command DP My version\Source.obj 1
Severity Code Description Project File Line Suppression State
Error LNK2019 unresolved external symbol "public: __thiscall AtkAirforce::AtkAirforce(void)" (??0AtkAirforce@@QAE@XZ) referenced in function _main Command DP My version C:\Users\ryanb\source\repos\Command DP My version\Command DP My version\Source.obj 1
==
Source.cpp
==
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
|
#include <iostream>
#include <string>
#include <vector>
#include "Player.h"
#include "Attack.h"
//class
int main() {
std::vector<AttackCmd*> Commands;
Player Ryan("Levi", Commands);
AttackCmd* cmd1 = new AtkInfantry;
Commands.push_back(cmd1);
AttackCmd* cmd2 = new AtkAirforce;
Commands.push_back(cmd2);
AttackCmd* cmd3 = new AtkAirforce;
Commands.push_back(cmd3);
AttackCmd* cmd4 = new AtkAirforce;
Commands.push_back(cmd4);
AttackCmd* cmd5 = new AtkNavy;
Commands.push_back(cmd5);
for (int i=Commands.size()-1; i >= 0 ; i--) {
//Commands[i]->Execute(Ryan);
}
delete cmd1;
//cmd3->Cancel(Ryan);
return 0;
}
| |
==
Player.h
==
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
#pragma once
#include <iostream>
#include <vector>
#include <string>
class AttackCmd;
class Player {
public:
std::string _name;
int attacks = 0;
std::vector<AttackCmd*> q;
Player(std::string name, std::vector<AttackCmd*>& queue);
void attack(std::string atk);
void stop();
};
| |
==
Player.cpp
==
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
|
#pragma once
#include <vector>
#include <iostream>
#include <string>
#include "Player.h"
#include "Attack.h"
//class AttackCmd;
Player::Player(std::string name, std::vector<AttackCmd*> &queue)
{
//std::cout << q.size();
}
void Player::attack(std::string atk) {
attacks++;
std::cout << "Attack no. " << attacks << ". " << _name << atk << std::endl;
}
void Player::stop()
{
q.pop_back();
std::cout << "Last command undone, iterating through command queue for confirmation: \n";
// for (int i = 1; i <= q.size(); i++) {
//q[i]->Execute(this);
//q[i]->Cancel;
// std::cout << q.size();
};
| |
==
Player.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
#pragma once
#include <iostream>
#include <vector>
#include <string>
class AttackCmd;
class Player {
public:
std::string _name;
int attacks = 0;
std::vector<AttackCmd*> q;
Player(std::string name, std::vector<AttackCmd*>& queue);
void attack(std::string atk);
void stop();
};
| |
==
Attack.h
==
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
|
#pragma once
//implementation of command design pattern for RTS or turn based Strategy game with multiple commands.
#include <iostream>
#include <vector>
#include <string>
#include "Player.h"
class AttackCmd {
public:
AttackCmd() ;
virtual void Execute(Player& play) = 0;
virtual void Cancel(Player& play) = 0;
};
class AtkInfantry : public AttackCmd
{
public:
AtkInfantry();
std::string type = "Infantry";
void Execute(Player& play);
void Cancel(Player& play);
};
class AtkNavy: public AttackCmd
{
public:
AtkNavy() ;
std::string type = "Navy";
void Execute(Player& play);
void Cancel(Player& play);
};
class AtkAirforce: public AttackCmd
{
public:
AtkAirforce() ;
std::string type = "Airforce";
void Execute(Player& play);
void Cancel(Player& play);
};
| |
==
Attack.cpp
==
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
|
#pragma once
#include <vector>
#include <iostream>
#include <string>
#include "Attack.h"
#include "Player.h"
//implementation of command design pattern for RTS or turn based Strategy game with multiple commands.
#pragma once
//virtual void AttackCmd::Execute(Player& play) = 0;
//virtual void AttackCmd::Cancel(Player& play) = 0;
//AtkInfantry::AtkInfantry() { std::cout << ""; }
void AtkInfantry::Execute(Player& play) {
play.attack(type);
play.q.push_back(this);
}
void AtkInfantry::Cancel(Player& play) {
play.stop(); }
//AtkNavy::AtkNavy() {};
void AtkNavy::Execute(Player& play) {
play.attack(type);
play.q.push_back(this);
}
void AtkNavy::Cancel(Player& play) { play.stop(); }
// AtkAirforce::AtkAirforce() {};
void AtkAirforce::Execute(Player& play)
{
play.attack(type);
play.q.push_back(this);
}
void AtkAirforce::Cancel(Player& play) { play.stop(); }
| |
Just to reiterate, I'd really appreciate some help on this, since it can be a vague error, or at least an error that needs some understanding of many areas of c++