I'm getting strange linking error in the main window. I also included the header files of those classes in main window. but still it can't link the virtual functions.
I'm using the following code that is in main:
S3W::IFields *recordsTx = pConnection->GetTransmittedFields();
FieldsDataList *derived = dynamic_cast<FieldsDataList*>(recordsTx);
for (int j = 0; j < 2; j++)
{
VarField& record = derived->CreateDataItem();
FieldsDataList *fields = record.getChildrenDataList();
VarField& fieldGeom1 = fields->CreateDataItem();
fieldGeom1.SetKey("geom");
double x = 47;
double y = 16;
fieldGeom1 = VarField::fromGPS(new ImplGps(x, y));
}
I'm getting the following link Error:
3>MainWindow.obj : error LNK2001: unresolved external symbol "public: virtual struct S3W::IFields & __thiscall VarField::getChildern(void)" (?getChildern#VarField##UAEAAUIFields#S3W##XZ)
3>MainWindow.obj : error LNK2001: unresolved external symbol "public: virtual struct FieldsDataList * __thiscall VarField::getChildrenDataList(void)"
Here is the class definition of the Classes:
// pseudo code
class VarField : public S3W::IField
{
virtual S3W::IFields& getChildern() override;
// Inherited via IField
virtual FieldsDataList * getChildrenDataList() override;
}
and IField is :
struct FieldsDataList;
namespace S3W
{
struct IFields;
struct IField : S3W::IListItem
{
enum class Type { NONE = 0, UINT = 1, DOUBLE = 2, STRING = 3 , GEOM = 4};
virtual S3W::IGps* getGeom() = 0;
virtual double getDouble() const = 0;
virtual unsigned int getUint() const = 0;
virtual const char* getString() const = 0;
virtual const char* getKey() const = 0;
virtual Type getType() const = 0;
virtual ~IField() { }
IField() {}
virtual IFields& getChildern()= 0;
virtual FieldsDataList* getChildrenDataList() = 0;
};
Related
I have this abstract class
class ImageIO {
protected:
ImageIO() {}
public:
virtual bool load(const std::string & filename, const std::string & format) = 0;
virtual bool save(const std::string & filename, const std::string & format) = 0;
}
And the implementation
class Image : public Array2D<Color>, public ImageIO {
private:
static int case_insensitive(string s) {
transform(s.begin(), s.end(), s.begin(), tolower);
if (s.compare("ppm") == 0) {
return 1;
}
return 0;
}
public:
bool load(const std::string& filename, const std::string& format) {
if (case_insensitive(format)) {
float* data = ReadPPM(filename.c_str(), (int*)width, (int*)height);
for (int i = 0, j = 0; i < width * height; i++, j += 3) {
buffer[i] = Color(data[j], data[j + 1], data[j + 2]);
}
delete[] data;
return true;
}
return false;
}
bool save(const std::string& filename, const std::string& format) {
if (case_insensitive(format)) {
float* data = new float[width * height * 3];
for (int i = 0, j = 0; i < width * height; i++, j += 3) {
data[j] = buffer[i].x;
data[j + 1] = buffer[i].y;
data[j + 2] = buffer[i].z;
}
bool write_check = WritePPM(data, width, height, filename.c_str());
delete[] data;
return write_check;
}
return false;
}
};
And I keep getting an abstract class cannot be instantiated error if I try this
Image test = Image();
in my main.
I've also tried declaring t=those two methods in a header file
class Image : public Array2D<Color>, public ImageIO {
private:
static int case_insensitive(std::string);
public:
bool ImageIO::load(const std::string& filename, const std::string& format);
bool ImageIO::save(const std::string& filename, const std::string& format);
};
but then I get unresolved external symbol errors. Is there a problem in the way I'm implementing the two functions or in how my declaring the class?
EDIT: If I declare those two methods in the header file then the error is:
error LNK2019: unresolved external symbol "public: virtual bool __thiscall image::Image::[image::ImageIO]::load(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)" (?load#?QImageIO#image##Image#2#UAE_NABV?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std##0#Z) referenced in function _main
error LNK2019: unresolved external symbol "public: virtual bool __thiscall image::Image::[image::ImageIO]::save(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)" (?save#?QImageIO#image##Image#2#UAE_NABV?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std##0#Z) referenced in function _main
If I don't the error is
error C2259: 'image::Image': cannot instantiate abstract class
I also added override and nothing changes.
To specifically answer the question about unresolved external symbols, you don't need the ImageIO parent specifier on the save/load functions. You are declaring that Image itself has those functions, which override the abstract functions on the parent. You will then need to specify Image when implementing them in the cpp file.
Image.hpp
class Image : public Array2D<Color>, public ImageIO {
private:
static int case_insensitive(std::string);
public:
bool load(const std::string& filename, const std::string& format) override;
bool save(const std::string& filename, const std::string& format) override;
};
Image.cpp
bool Image::load(const std::string& filename, const std::string& format) {
if (case_insensitive(format)) {
//etc.
}
return false;
}
bool Image::save(const std::string& filename, const std::string& format) {
if (case_insensitive(format)) {
//etc.
}
return false;
}
This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 5 years ago.
#include <iostream>
#include <map>
#include <string>
#include <cstdlib>
using namespace std;
class Shape
{
public :
virtual void draw()=0;
virtual ~Shape(){}
};
class Circle : public Shape
{
string color;
int x;
int y;
int radius;
public:
Circle(string color){
color = color;
}
void setX(int x) {
x = x;
}
void setY(int y) {
y = y;
}
void setRadius(int radius) {
radius = radius;
}
void draw() {
cout << "color :" << color << x << y ;
}
};
class ShapeFactory {
public:
static map<string, Shape*> circlemap;
static Shape* getcircle(string color)
{
Shape *mcircle;
mcircle = circlemap.find(color)->second;
if(mcircle == nullptr) {
mcircle = new Circle(color);
circlemap[color] = mcircle;
// circlemap.insert(std::make_pair(color,mcircle));
}
return mcircle;
}
};
class Flyweightpattern
{
public:
static string getRandomColor(string colors[]) {
int m_rand = rand() % 5;
return colors[m_rand];
}
static int getRandomX() {
return (int)(rand() % 100);
}
static int getRandomY() {
return (int)(rand() % 100);
}
};
int main()
{
string colors[] = { "Red", "Green", "Blue", "White", "Black" };
for(int i=0; i < 20; ++i) {
Circle *circle = dynamic_cast<Circle *>(ShapeFactory::getcircle(Flyweightpattern::getRandomColor(colors)));
circle->setX(Flyweightpattern::getRandomX());
circle->setY(Flyweightpattern::getRandomY());
circle->setRadius(100);
circle->draw();
}
getchar();
return 0;
}
I am getting the linking error during run is below :
flyweight_pattern.obj : error LNK2001: unresolved external symbol
"public: static class std::map,class std::allocator >,class Circle
*,struct std::less,class std::allocator > >,class
std::allocator,class std::allocator > const ,class
Circle *> > > ShapeFactory::circlemap"
(?circlemap#ShapeFactory##2V?$map#V?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std##PAVCircle##U?$less#V?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std###2#V?$allocator#U?$pair#$$CBV?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std##PAVCircle###std###2##std##A)
I have a map in the ShapeFactory class and tried to creating filling the map in the class itself but still not able to resolve the problem.
You didn't defined circlemap, it's a static member, so you should define it (and initialize) in global scope:
map<string, Shape*> ShapeFactory::circlemap = {};
Integral nonvolatile static members can be initialized in class.
Oh, and it is not recommended to do using namespace std; in global scope, that leads to side effects.
You can write something like
using std::map;
to target selected id (map in this case), and you can write using in namespace that contains usage.
My program compiles, but I get the following link errors:
1>desalter.obj : error LNK2020: unresolved token (0A000065) "private: static double (* DataBace::Number_d_save)[110]" (?Number_d_save#DataBace##$$Q0PAY0GO#NA)
1>desalter.obj : error LNK2020: unresolved token (0A000066) "private: static double (* DataBace::Flow_spec)[5]" (?Flow_spec#DataBace##$$Q0PAY04NA)
1>desalter.obj : error LNK2020: unresolved token (0A000068) "private: static class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > * DataBace::Flow_Name" (?Flow_Name#DataBace##$$Q0PAV?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std##A)
1>desalter.obj : error LNK2001: unresolved external symbol "private: static double (* DataBace::Flow_spec)[5]" (?Flow_spec#DataBace##$$Q0PAY04NA)
1>desalter.obj : error LNK2001: unresolved external symbol "private: static double (* DataBace::Number_d_save)[110]" (?Number_d_save#DataBace##$$Q0PAY0GO#NA)
1>desalter.obj : error LNK2001: unresolved external symbol "private: static class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > * DataBace::Flow_Name" (?Flow_Name#DataBace##$$Q0PAV?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std##A)
1>C:\Users\Mojtaba Mohayeji\Documents\Visual Studio 2010\Projects\desalter\Debug\desalter.exe : fatal error LNK1120: 6 unresolved externals
Code:
class DataBace
{
public:
//---
void fLOW_NAME(int indicator, string flow_name)
{
Flow_Name[indicator] = flow_name;
}
string** fLOW_NAME_READ()
{
string** flow_name_read = new string*[1];
for (int i = 1; i < 100; i++)
{
string a = Flow_Name[i];
flow_name_read[i] = &a;
}
return flow_name_read;
}
int Show(string show)
{
for (int i = 0; i < 100; i++)
{
string sh = Flow_Name[i];
if (sh==show)
{
return i;
}
}
}
void FLOW_SPEC(int indicator, double flow_spec[1][5])
{
for (int i = 0; i < 5; i++)
{
Flow_spec[indicator][i] = flow_spec[1][i];
}
}
double** FLOW_SPEC_READ(int SHOW)
{
double** flow_spec_read = new double*[5];
for (int i = 1; i < 5; i++)
{
double a = Flow_spec[SHOW][i];
flow_spec_read[i] = &a;
}
return flow_spec_read;
}
void Number_d_SAVE(int indicator, double Number_d[110])
{
for (int i = 0; i < 110; i++)
{
Number_d_save[indicator][i] = Number_d[i];
}
}
double** Number_d_READ(int SHOW)
{
double** Number_d_read = new double*[110];
for (int i = 1; i < 110; i++)
{
double a = Number_d_save[SHOW][i];
Number_d_read[i] = &a;
}
return Number_d_read;
}
private:
static string Flow_Name[100];
static double Flow_spec[100][5];
static double Number_d_save[100][110];
};
I have written this code using SDL but there are some errors.
This is the code
#include <SDL.h>
#include <SDL_image.h>
#include <SDL_ttf.h>
#include <SDL_mixer.h>
#include <fstream>
#include <iostream>
using namespace std;
/////////////////////////////////// functions & global variable ////////////////////////////////
SDL_Window* window;
SDL_Renderer* renderer;
SDL_Color textColor;
TTF_Font* font;
SDL_Surface* surface=SDL_GetWindowSurface(window);
SDL_Event event;
SDL_Texture* LoadTexture(char* path)
{
SDL_Surface* surface = IMG_Load(path);
SDL_Texture* texture = SDL_CreateTextureFromSurface(renderer,surface);
SDL_FreeSurface(surface);
return texture;
}
///////////////////////////////////// Cell /////////////////////////////////////
class Cell
{
private:
char num;
public:
Cell();
Cell(int ,int ,char);
char * img;
pair <int ,int> cor;
int flag;
int size;
void display();
bool indomain(int ,int);
};
Cell :: Cell(int x ,int y ,char n){
num=n;
cor.first=x;
cor.second=y;
size=40;
flag=0;
if (num == '#')
img="0.png";
else if (num == '!')
img="1.png";
else
img="street.png";
}
bool Cell :: indomain(int x ,int y){
if ( (cor.first<=x && x<=cor.first+size) && (cor.second<=y && y<=cor.second+size))
return true;
return false;
}
void Cell :: display(){
SDL_Rect rect;
rect.x=cor.first;
rect.y=cor.second;
SDL_Texture* texture = LoadTexture(img);
SDL_RenderCopy(renderer,texture,NULL,&rect);
}
//////////////////////////////////////////// Tower /////////////////////////////////////////
class Tower
{
public:
Tower();
Tower(int ,int ,int ,int ,char* ,int ,int ,int);
~Tower();
int price;
int up_cost;
char * img;
int power;
int domain;
int grade;
int index;
pair <int ,int> cor;
void upgrade();
void display();
bool mark(int ,int);
};
Tower :: Tower(int pr ,int co ,int pow ,int dom ,char* im ,int x ,int y ,int i){
price=pr;
up_cost=co;
power=pow;
domain=dom;
img=im;
cor.first=x;
cor.second=y;
grade=1;
index=i;
}
void Tower :: upgrade(){
if (grade<5)
{
grade+=1;
power*=2;
domain*=1.2;
price*=1.2;
}
}
void Tower :: display(){
SDL_Rect rect;
rect.x=cor.first;
rect.y=cor.second;
SDL_Texture* texture = LoadTexture(img);
SDL_RenderCopy(renderer,texture,NULL,&rect);
}
bool Tower :: mark(int x, int y){
if ((cor.first<=x && x<=cor.first+40) && (cor.second<=y && x<=cor.second+80))
return true;
return false;
}
//////////////////////////////// Enemy //////////////////////////////////////
class Enemy
{
public:
Enemy();
Enemy(int ,char* ,int ,int ,int);
~Enemy();
char * img;
int health;
int cellNum;
int index;
pair <int ,int> cor;
bool live();
void display();
void damge(Tower t);
};
Enemy :: Enemy(int h ,char* im ,int x ,int y ,int i){
health=h;
img=im;
cor.first=x;
cor.second=y;
cellNum=0;
index=i;
}
bool Enemy :: live(){
if (health>0)
return true;
return false;
}
void Enemy :: damge(Tower t){
health-=t.power;
}
void Enemy :: display(){
SDL_Rect rect;
rect.x=cor.first;
rect.y=cor.second;
SDL_Texture* texture = LoadTexture(img);
SDL_RenderCopy(renderer,texture,NULL,&rect);
}
///////////////////////////////////////////// Map ///////////////////////////////////////
class Map
{
private:
char * file;
int len;
public:
Map();
Map(char* ,int);
~Map();
Cell map[15][20];
pair <int ,int> * path;
void display();
void put_tower(Tower ,Cell);
void put_enemy(Enemy ,Cell);
void remove(Cell);
void enemyMove(Enemy);
void pathFinder(int);
};
Map :: Map(char * f ,int l){
file=f;
len=l;
ifstream infile;
infile.open(file);
char * line=new char;
for (int i=0;i<15;i++)
{
infile >> line;
for (int j=0;j<20;j++)
map[i][j]=Cell(j*40 ,i*40 ,line[j]);
}
this->pathFinder(len);
}
void Map :: put_enemy(Enemy e ,Cell c){
e.cor=c.cor;
e.display();
}
void Map :: put_tower(Tower t ,Cell c){
t.cor=c.cor;
t.display();
}
void Map :: remove(Cell c){
c.display();
}
void Map :: enemyMove(Enemy e){
e.cellNum+=1;
e.cor=path[e.cellNum];
}
void Map :: pathFinder(int l){
path=new pair<int ,int> [l];
ifstream infile;
infile.open(file);
char ** lines=new char* [15];
for (int i=0;i<15;i++)
infile >> lines[i];
for (int i=0;i<20;i++)
if (lines[0][i]=='0')
{
path[0]=make_pair(0,i);
break;
}
int x=0;
int y=path[0].second;
int ord=48;
for (int i=1;i<l;i++)
{
if (int(lines[x-1][y])==((ord-47)%10)+48)
x-=1;
else if (int(lines[x+1][y])==((ord-47)%10)+48)
x+=1;
else if (int(lines[x][y-1])==((ord-47)%10)+48)
y-=1;
else if (int(lines[x][y+1])==((ord-47)%10)+48)
y+=1;
path[i]=make_pair(x,y);
ord+=1;
}
}
void Map :: display(){
for (int i=0;i<15;i++)
for (int j=0;j<20;j++)
map[i][j].display();
}
//////////////////////////////////////////////////// Game ////////////////////////////////////////
class Game
{
private:
int health;
int money;
int score;
int step;
public:
Game(int ,int);
~Game();
bool End;
int enemyNum;
int towerNum;
Enemy enemys[20];
Tower towers[50];
int getHealth();
int getMoney();
int getScore();
int getStep();
void setHealth(int);
void setMoney(int);
void setScore(int);
void setStep(int);
void distroy_enemy(Enemy ,Cell);
void distroy_tower(Tower ,Cell);
void shooting(Tower);
void drag_drop(Tower);
void upgradeTower(Tower);
void buyTower(Tower);
void sellTower(Tower ,Cell);
void display(Map);
void displayMenu();
void endDisplay();
bool checkEnd();
void animation();
};
Game :: Game(int h ,int m){
health=h;
money=m;
step=1;
score=0;
enemyNum=0;
towerNum=0;
End=false;
}
int Game :: getHealth(){
return health;
}
int Game :: getMoney(){
return money;
}
int Game :: getScore(){
return score;
}
int Game :: getStep(){
return step;
}
void Game :: setHealth(int h){
health=h;
}
void Game :: setMoney(int m){
money=m;
}
void Game :: setScore(int s){
score=s;
}
void Game :: setStep (int s){
step=s;
}
void Game :: distroy_enemy(Enemy e,Cell c){
for (int i=e.index;i<enemyNum-1;i++)
enemys[i]=enemys[i+1];
enemyNum-=1;
c.display();
}
void Game :: distroy_tower(Tower t ,Cell c){
for (int i=t.index;i<towerNum-1;i++)
towers[i]=towers[i+1];
towerNum-=1;
c.display();
}
void Game :: shooting(Tower t){
for(int i=0;i<enemyNum;i++)
{
if (sqrt(pow(enemys[i].cor.first,2)+pow(enemys[i].cor.second,2)) <= t.domain)
enemys[i].health-=t.power;
}
}
void Game :: upgradeTower(Tower t){
t.upgrade();
money-=t.up_cost;
}
void Game :: buyTower(Tower t){
money-=t.price;
towers[towerNum]=t;
towerNum+=1;
t.display();
}
void Game :: sellTower(Tower t ,Cell c){
distroy_tower(t,c);
money+=t.price/2;
}
void Game :: endDisplay(){
End=true;
SDL_FillRect(surface,&surface->clip_rect,SDL_MapRGB(surface->format,0XFF,0XFF,0XFF));
SDL_Surface* text;
font=TTF_OpenFont("AV.TTF",40);
textColor.b=20;
textColor.g=10;
textColor.r=0;
if (health<=0)
{
text=TTF_RenderText_Solid(font ,"You lose" ,textColor);
}
else if (health>0)
{
text=TTF_RenderText_Solid(font ,"Complete the mission" ,textColor);
}
SDL_Rect rect;
rect.x=300;
rect.y=300;
SDL_BlitSurface(text,NULL,surface,&rect);
}
bool Game :: checkEnd(){
if (health<=0 || step==20)
return true;
return false;
}
void Game :: displayMenu(){
SDL_Rect rect;
rect.x=800;
rect.y=0;
SDL_Texture* texture = LoadTexture("menu.png");
SDL_RenderCopy(renderer,texture,NULL,&rect);
}
void Game :: display(Map m){
m.display();
for (int i=0;i<towerNum;i++)
towers[i].display();
for (int i=0;i<enemyNum;i++)
enemys[i].display();
this->displayMenu();
/////////// ttf
}
void Game :: animation(){
SDL_Rect Lrect;
Lrect.x=83;
Lrect.y=0;
SDL_Rect Rrect;
Rrect.x=915;
Rrect.y=0;
SDL_Texture* leftpic = LoadTexture("left.png");
SDL_Texture* rightpic = LoadTexture("right.png");
for (int i=0;i<12;i++)
{
SDL_RenderCopy(renderer,leftpic,NULL,&Lrect);
SDL_RenderCopy(renderer,rightpic,NULL,&Rrect);
Rrect.x-=20;
Lrect.x+=60;
SDL_RendererFlip();
SDL_Delay(300);
}
}
////////////////////////////////////////////////////////////// main //////////////////////////////////////////////////////////////////////
int main()
{
window=SDL_CreateWindow("Frontline Defence",SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,940,600,SDL_WINDOW_SHOWN);
Game game(1000,500);
Map map("map.txt",30);
while ( !game.checkEnd() )
{
if ( SDL_PollEvent(&event))
{
if (event.type == SDL_QUIT)
return 0;
if (event.type == SDL_MOUSEBUTTONDOWN )
{
SDL_Delay(3000);
}
}
}
game.endDisplay();
return 0;
}
I've done every thing I could but nothing changed!
I've tried including the libraries , typing all parts of the code in the main file and many other ways but it didn't help
These are the errors:
Error 12 error LNK1120: 8 unresolved externals C:\Users\FUJITSU\Desktop\frontline defence\project\ConsoleApplication1\Debug\ConsoleApplication1.exe ConsoleApplication1
Error 4 error LNK2019: unresolved external symbol "public: __thiscall Cell::Cell(void)" (??0Cell##QAE#XZ) referenced in function "public: __thiscall Map::Map(char *,int)" (??0Map##QAE#PADH#Z) C:\Users\FUJITSU\Desktop\frontline defence\project\ConsoleApplication1\ConsoleApplication1\classes.obj ConsoleApplication1
Error 8 error LNK2019: unresolved external symbol "public: __thiscall Enemy::~Enemy(void)" (??1Enemy##QAE#XZ) referenced in function "public: __thiscall Game::Game(int,int)" (??0Game##QAE#HH#Z) C:\Users\FUJITSU\Desktop\frontline defence\project\ConsoleApplication1\ConsoleApplication1\classes.obj ConsoleApplication1
Error 7 error LNK2019: unresolved external symbol "public: __thiscall Enemy::Enemy(void)" (??0Enemy##QAE#XZ) referenced in function "public: __thiscall Game::Game(int,int)" (??0Game##QAE#HH#Z) C:\Users\FUJITSU\Desktop\frontline defence\project\ConsoleApplication1\ConsoleApplication1\classes.obj ConsoleApplication1
Error 10 error LNK2019: unresolved external symbol "public: __thiscall Game::~Game(void)" (??1Game##QAE#XZ) referenced in function "int __cdecl SDL_main(void)" (?SDL_main##YAHXZ) C:\Users\FUJITSU\Desktop\frontline defence\project\ConsoleApplication1\ConsoleApplication1\classes.obj ConsoleApplication1
Error 9 error LNK2019: unresolved external symbol "public: __thiscall Map::~Map(void)" (??1Map##QAE#XZ) referenced in function "int __cdecl SDL_main(void)" (?SDL_main##YAHXZ) C:\Users\FUJITSU\Desktop\frontline defence\project\ConsoleApplication1\ConsoleApplication1\classes.obj ConsoleApplication1
Error 6 error LNK2019: unresolved external symbol "public: __thiscall Tower::~Tower(void)" (??1Tower##QAE#XZ) referenced in function "public: __thiscall Game::Game(int,int)" (??0Game##QAE#HH#Z) C:\Users\FUJITSU\Desktop\frontline defence\project\ConsoleApplication1\ConsoleApplication1\classes.obj ConsoleApplication1
Error 5 error LNK2019: unresolved external symbol "public: __thiscall Tower::Tower(void)" (??0Tower##QAE#XZ) referenced in function "public: __thiscall Game::Game(int,int)" (??0Game##QAE#HH#Z) C:\Users\FUJITSU\Desktop\frontline defence\project\ConsoleApplication1\ConsoleApplication1\classes.obj ConsoleApplication1
Error 11 error LNK2019: unresolved external symbol _SDL_main referenced in function _main C:\Users\FUJITSU\Desktop\frontline defence\project\ConsoleApplication1\ConsoleApplication1\SDL2main.lib(SDL_windows_main.obj) ConsoleApplication1
You're getting the linker errors referencing constructors and destructors because you haven't provided any implementation for those functions (as Michael Burr pointed out in a comment).
The unresolved external symbol _SDL_main referenced in function _main is because the mainfunction needs to have a specific signature: int main(int argc, char* argv[]) and check that you also have the SDL2main.libin the input to the linker.
Finally, it would seem that you never create any renderer (unless you create somewhere not included in your code example), so you have to add a call to SDL_CreateRenderer() after you create the SDL_Window in main.
EDIT: I basically revamped the whole question so I could provide an executable example...
I have been getting a segmentation fault that I can't figure out. Here is a compacted version of my code. I maintained the original class hierarchy even though some of the classes have no relevant methods since I think that it has something to do with my issue, especially after some of the comments I've been getting.
#import <vector>
using namespace std;
template<class Data = float>
class Vector
{
// All pure virtual functions.
};
template<class Data>
class TranslationVector : public virtual Vector<Data>
{
// All pure virtual functions.
};
template<class Data>
class SimpleVector4 : public virtual Vector<Data>
{
public:
SimpleVector4(const Data d0, const Data d1, const Data d2, const Data d3)
{
fData = new vector<Data> ;
fData->push_back(d0);
fData->push_back(d1);
fData->push_back(d2);
fData->push_back(d3);
}
vector<Data>*
getData()
{
return (fData);
}
private:
vector<Data>* fData;
};
template<class Data>
class SimpleTranslationVector4 : public SimpleVector4<Data> , public TranslationVector<Data>
{
public:
SimpleTranslationVector4(const Data x, const Data y, const Data z, const Data w) :
SimpleVector4<Data> (x, y, z, w)
{
}
};
template<class Data = float>
class Matrix
{
// All pure virtual functions.
};
template<class Data>
class TransformationMatrix : public virtual Matrix<Data>
{
// All pure virtual functions.
virtual void
translate(TranslationVector<Data>* const translation) = 0;
};
template<class Data>
class SimpleMatrix44 : public virtual Matrix<Data>
{
public:
SimpleMatrix44()
{
fData = new vector<Data> (CELLS_IN_MATRIX, 0);
setIdentity();
}
vector<Data>*
getData()
{
return (fData);
}
void
setIdentity()
{
fData->at(0) = 1;
fData->at(1) = 0;
fData->at(2) = 0;
fData->at(3) = 0;
fData->at(4) = 0;
fData->at(5) = 1;
fData->at(6) = 0;
fData->at(7) = 0;
fData->at(8) = 0;
fData->at(9) = 0;
fData->at(10) = 1;
fData->at(11) = 0;
fData->at(12) = 0;
fData->at(13) = 0;
fData->at(14) = 0;
fData->at(15) = 1;
}
private:
static const int CELLS_IN_MATRIX = 16;
vector<Data>* fData;
};
template<class Data>
class SimpleTransformationMatrix44 : public SimpleMatrix44<Data> , public TransformationMatrix<Data>
{
public:
SimpleTransformationMatrix44() :
SimpleMatrix44<Data> ()
{
}
void
translate(TranslationVector<Data>* translation)
{
vector<Data> *data = SimpleMatrix44<Data>::getData();
vector<Data> *transData = ((SimpleVector4<Data>*) translation)->getData();
// The error occurs on this line:
data->at(12) += data->at(0) * transData->at(0) + data->at(4) * transData->at(1) + data->at(8) * transData->at(2);
data->at(13) += data->at(1) * transData->at(0) + data->at(5) * transData->at(1) + data->at(9) * transData->at(2);
data->at(14) += data->at(2) * transData->at(0) + data->at(6) * transData->at(1) + data->at(10) * transData->at(2);
data->at(15) += data->at(3) * transData->at(0) + data->at(7) * transData->at(1) + data->at(11) * transData->at(2);
}
};
int
main(int argc, char** argv)
{
SimpleTransformationMatrix44<float> matrix1;
matrix1.translate(new SimpleTranslationVector4<float> (0.0f, 10.0f, 0.0f, 1.0f));
return 0;
}
I have commented in the code where the error occurs. From debugging I can see that it actually occurs in the size() function of vector and that transData has not been initialized. I can't for the life of me figure out why transData has not been initialized! Any ideas?
Thanks,
Gaz.
Cast of non-inherited classes seems to be your error.
Let's see your code. There is a conversion of SimpleTranslationVector4<float>* to TranslationVector<float>* while invoking the translate function. Then the converted value is converted again into SimpleVector4<float>*. But the SimpleVector4<float> does not inherit TranslationVector<float>.
This code also results in error.
template<class Data>
class SimpleVector4 {
public:
int a;
};
template<class Data>
class TranslationVector {
};
template<class Data>
class SimpleTranslationVector4 : public SimpleVector4<Data>,
public TranslationVector<Data> {
};
int main() {
SimpleTranslationVector4<float> A;
SimpleVector4<float>* b = (SimpleVector4<float>*)&A;
TranslationVector<float>* c = (TranslationVector<float>*)&A;
SimpleVector4<float>* d = (SimpleVector4<float>*)c;
b->a = 1; // ok
d->a = 1; // error
}
You're doing a C-style cast between unrelated types. This is not safe. The fact that you need to do this at all probably indicates a problem in your design, but try replacing this:
vector<Data>* transData = ((SimpleVector4<Data>*) translation)->SimpleVector4<Data>::getData();
with this:
vector<Data>* transData = dynamic_cast<SimpleVector4<Data>*>(translation)->getData();