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

Started by
3 comments, last by StoneMask 10 years, 7 months ago

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]

Advertisement

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

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)

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.

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!

This topic is closed to new replies.

Advertisement