• Advertisement
Sign in to follow this  

[fixed] Unresolved external symbol error; related to [virtual] inheritance?

This topic is 1587 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'm trying to work out a simple, functioning game engine, and I'm starting out as basic as I think I can get.

 

I have a virtual base class, Entity; the only child class I have for it currently is the Block class. I have a SceneManager class that contains a vector of Entity pointers, and with the Init() function, I attempt to populate it with Block objects, using an overloaded constructor. At first I thought it was because I did not have a corresponding overloaded constructor in the base class, but even when I added it, I got the same error:

 

-

LNK2019: unresolved external symbol "public: __thiscall Entity::Entity(void)" referenced in function "public: __thiscall Block::Block(short,short)"

-

 

This is my code:

 

Entity.hpp

[spoiler]

#pragma once

/* Entity.hpp
   - base class for all entities
   - also contains flag enumerations specifically for general entity and enemy-like types
   */

#include "Collision.hpp"
#include "Vector.hpp"
#include <Windows.h>

enum EnemyFlags
{
	enInit    = 0x01,
	enAlive   = 0x02,
	enScared  = 0x04,
	enHiding  = 0x08,
	enBeaming = 0x10
};

enum EntityIDs
{
	eIDBlock = 0x01,
	eIDRed   = 0x02,
	eIDBlu   = 0x04,
	eIDGrn   = 0x08
};

class Entity
{
	static unsigned short Count;

public:
	Entity();
	virtual void Init()  = 0;
	virtual void Act()   = 0;
	virtual bool Alive() = 0;
	virtual void Draw(const HANDLE)  = 0;
	virtual Collision Collide(Entity*) = 0;
	const COORD GetPos() { return Position; };
	const __int32 ID;

protected:
	virtual void Move() = 0;
	virtual void Die()  = 0;

	COORD* Beacon;
	COORD  Position;
	Vector Velocity;
	Vector Dimensions;
	char   Flags;
	char   Frames[4];
	short CurFrame, EndFrame;
	short FrameDelay, FrameTimer;
	unsigned short Timer;
};

[/spoiler]

 

Block.hpp

[spoiler]

#pragma once

/* Block.hpp
   - stores information about block objects
   - contains a position and dimensions
   */

#include "Entity.hpp"

class Block : public Entity
{
public:
	Block();
	Block(short, short);

	void Init();
	void Act();
	bool Alive();
	void Draw(const HANDLE);
	Collision Collide(Entity*);
	const __int32 ID;

protected:
	void Move();
	void Die();
	
	COORD  Position;
	Vector Dimensions;
	Vector Velocity;
};

[/spoiler]

 

Block.cpp

[spoiler]

// Block.cpp

#include "Block.hpp"
#include <iostream>

Block::Block() :
	ID (eIDBlock)
{
	// empty for now
}

Block::Block(short x, short y) :
	ID (eIDBlock)
{
	Position.X = x;
	Position.Y = y;
	Dimensions.X = 16;
	Dimensions.Y = 16;
	Velocity.X = 0;
	Velocity.Y = 0;
}

void Block::Draw(const HANDLE backbuffer)
{
	SetConsoleCursorPosition(backbuffer, Position);
	std::cout << char(219);
}

Collision Block::Collide(Entity* other)
{
	// blank for now

	Collision info;
	info.Contact = false;
	info.Intersection.X = 0;
	info.Intersection.Y = 0;
	info.Intersection.Z = 0;
	info.OtherID = 0;
	info.Velocity.X = 0;
	info.Velocity.Y = 0;
	info.Velocity.Z = 0;

	return info;
}

void Block::Move()
{
	// empty for now
}

void Block::Init()
{
	// empty for now
}

void Block::Act()
{
	// empty for now
}

bool Block::Alive()
{
	return true;
}

void Block::Die()
{
	// empty for now
}

[/spoiler]

 

SceneManager.cpp

[spoiler]

// SceneManager.cpp

#include <fstream>
#include "SceneManager.hpp"
#include "Block.hpp"

SceneManager::SceneManager():
	hOut(GetStdHandle(STD_OUTPUT_HANDLE))
{
	// empty for now
}

void SceneManager::Init(__int32 stateID, short info)
{
	// depending on which state ID is given, it loads from an information file depending on info
	for (short col = 0; col < 80; col++)
		for (short row = 0; row < 25; row++)
			Entities.push_back(new Block(col, row));
}

void SceneManager::Quit()
{
	// empty for now
}

void SceneManager::Tick()
{
	for (unsigned short i = 0; i < Entities.size(); i++)
		Entities[i]->Draw(hOut);
}

void SceneManager::Save()
{
	// empty for now
}

void SceneManager::Load()
{
	// empty for now
}

[/spoiler]

Share this post


Link to post
Share on other sites
Advertisement

You need to supply a body for your Entity constructor if you declare it in the class definition.

Share this post


Link to post
Share on other sites

If I insert

-

Entity::Entity():
	ID (eIDBlock)
{
	// empty for now
};

-

into the code, I get these errors:

-

LNK2005: "public: __thiscall Entity::Entity(void)" already defined in Block.obj (GamePlay.obj)
LNK2005: "public: __thiscall Entity::Entity(void)" already defined in Block.obj (SceneManager.obj)
LNK2005: "public: __thiscall Entity::Entity(void)" already defined in Block.obj (StateFactory.obj)
Edited by Akashi

Share this post


Link to post
Share on other sites

Are you putting that in a header file? Function definitions in a header file need to be defined as inline. If you don't want to make it an inline function put the function definition in a source file.

Share this post


Link to post
Share on other sites

Oh, there we go. I thought I'd just do a quick fix and put the source in the header file, but now I've learned why that can mess things up.

 

Problem solved. Thanks!

Share this post


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

  • Advertisement