Advertisement Jump to content
Sign in to follow this  
Tispe

Double Dispatch errors

This topic is 1797 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have tried to implement double dispatch. But I get errors:

 

Error 1 error C2027: use of undefined type 'InstructionAdd'
Error 2 error C2228: left of '.Data' must have class/struct/union
Error 3 error C2228: left of '.ID' must have class/struct/union

 

They appear in the Processer (PlayerManager) class, what am I doing wrong?

struct PlayerData 
{
	DWORD ID;
	float Pos[3];
};

struct MessageBase 
{
	DWORD Type;
	DWORD Size;
};

struct MessageAdd : MessageBase
{
	DWORD ID;
	float Pos[3];
};

struct MessageRemove : MessageBase 
{
	DWORD ID;
};

struct MessagePos : MessageBase 
{
	DWORD ID;
	float Pos[3];
};
struct InstructionBase;
struct InstructionAdd;
struct InstructionRemove;
struct InstructionPos;

class PlayerManager
{
public:
	void Process(InstructionBase& nothing);
	void Process(InstructionAdd& add)
	{
		std::shared_ptr<PlayerData> spNewPlayer(new PlayerData);
		PlayersMap[add.Data.ID] = spNewPlayer;						//Errors are here!
	}
	void Procces(InstructionRemove& remove);
	void Procces(InstructionPos& pos);
private:
	std::map<DWORD, std::shared_ptr<PlayerData> > PlayersMap;
};

struct InstructionBase 
{
	virtual void Process(PlayerManager& processer){
		processer.Process(*this);
	}
};

struct InstructionAdd : InstructionBase
{
	MessageAdd Data;
	virtual void Process(PlayerManager& processer){
		processer.Process(*this);
	}
};

struct InstructionRemove : InstructionBase
{
	MessageRemove Data;
	virtual void Process(PlayerManager& processer){
		processer.Process(*this);
	}
};

struct InstructionPos : InstructionBase
{
	MessagePos Data;
	virtual void Process(PlayerManager& processer){
		processer.Process(*this);
	}
};
//Example
int main(){
	PlayerManager Players;
	std::queue<std::shared_ptr<InstructionBase> > Instructions;

	//GetNewInstructions(Instructions);

	while(!Instructions.empty()){
		Instructions.front()->Process(Players);
		Instructions.pop();
	}

	return 0;
}

Share this post


Link to post
Share on other sites
Advertisement

Everything is forward declared already. Before "PlayersMap[add.Data.ID] = spNewPlayer;" is called, all structures are either declared or forward declared. 

Share this post


Link to post
Share on other sites

Thanks, got it working by moving the class implementation after the declarations.

#define	MsgAddPlayer		1
#define	MsgRmvPlayer		2
#define	MsgPosPlayer		3

struct PlayerData 
{
	DWORD ID;
	float Pos[3];
};

struct MessageBase 
{
	DWORD Type;
	DWORD Size;
};

struct MessageAdd : MessageBase
{
	DWORD ID;
	float Pos[3];
};

struct MessageRemove : MessageBase 
{
	DWORD ID;
};

struct MessagePos : MessageBase 
{
	DWORD ID;
	float Pos[3];
};

struct InstructionBase;
struct InstructionAdd;
struct InstructionRemove;
struct InstructionPos;

class PlayerManager
{
public:
	void Process(InstructionBase& nothing);
	void Process(InstructionAdd& add);
	void Procces(InstructionRemove& remove);
	void Procces(InstructionPos& pos);
//private:
	std::map<DWORD, std::shared_ptr<PlayerData> > PlayersMap;
};

struct InstructionBase 
{
	virtual void Process(PlayerManager& processer){
		processer.Process(*this);
	}
};

struct InstructionAdd : InstructionBase
{
	MessageAdd Data;
	InstructionAdd(DWORD ID, float x, float y, float z)
	{
		Data.Type = MsgAddPlayer;
		Data.ID = ID;
		Data.Pos[0] = x;
		Data.Pos[1] = y;
		Data.Pos[2] = z;
	}
	virtual void Process(PlayerManager& processer){
		processer.Process(*this);
	}
};

struct InstructionRemove : InstructionBase
{
	MessageRemove Data;
	InstructionRemove(DWORD ID)
	{
		Data.Type = MsgRmvPlayer;
		Data.ID = ID;
	}
	virtual void Process(PlayerManager& processer){
		processer.Process(*this);
	}
};

struct InstructionPos : InstructionBase
{
	MessagePos Data;
	InstructionPos(DWORD ID, float x, float y, float z)
	{
		Data.Type = MsgPosPlayer;
		Data.ID = ID;
		Data.Pos[0] = x;
		Data.Pos[1] = y;
		Data.Pos[2] = z;
	}
	virtual void Process(PlayerManager& processer){
		processer.Process(*this);
	}
};

void PlayerManager::Process(InstructionBase& nothing)
{
}

void PlayerManager::Process(InstructionAdd& add)
{
	std::shared_ptr<PlayerData> spNewPlayer(new PlayerData);
	PlayersMap[add.Data.ID] = spNewPlayer;
	spNewPlayer->Pos[0] = add.Data.Pos[0];
	spNewPlayer->Pos[1] = add.Data.Pos[1];
	spNewPlayer->Pos[2] = add.Data.Pos[2];
}

void PlayerManager::Procces(InstructionRemove& remove)
{
	PlayersMap.erase(remove.Data.ID);
}

void PlayerManager::Procces(InstructionPos& pos)
{
	PlayersMap[pos.Data.ID]->Pos[0] = pos.Data.Pos[0];		//x
	PlayersMap[pos.Data.ID]->Pos[1] = pos.Data.Pos[1];		//y
	PlayersMap[pos.Data.ID]->Pos[2] = pos.Data.Pos[2];		//z
}

void GetNewInstructions(std::queue<std::shared_ptr<InstructionBase> > &Instructions)
{
	Instructions.push(std::make_shared<InstructionAdd>(17, 1.0f, 0.0f, 5.0f));
	Instructions.push(std::make_shared<InstructionAdd>(7, 16.0f, 0.0f, 15.0f));
	Instructions.push(std::make_shared<InstructionAdd>(89, -11.0f, 0.0f, 55.0f));
}

//Example
int main(){
	PlayerManager Players;
	std::queue<std::shared_ptr<InstructionBase> > Instructions;

	GetNewInstructions(Instructions);

	while(!Instructions.empty()){
		Instructions.front()->Process(Players);
		Instructions.pop();
	}

	std::cout << Players.PlayersMap[89]->Pos[0] << std::endl;
	std::cout << Players.PlayersMap[89]->Pos[1] << std::endl;
	std::cout << Players.PlayersMap[89]->Pos[2] << std::endl;

	return 0;
}

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!