I have incorporated polymorphism with a single subclass for now. Two of these functions, as seen in the following code, Draw() and SetValue(int,int,int) are causing linker errors.
#include "Header.h"
class Object{
int tag;
public:
void SetValues(int,int,int);
void Draw();
int getTag(){
return tag;
}
};
class Square: public Object{
int red;
int green;
int blue;
void Draw();
void SetValues(int red2,int green2, int blue2){
red=red2;
green=green2;
blue=blue2;
}
};
void Square::Draw(){
// Draws a square with a gradient color at coordinates 0, 10
glBegin(GL_QUADS);
{
glColor3f(red, green, blue);
glVertex2i(1, 11);
glColor3f(red * .8, green * .8, blue * .8);
glVertex2i(-1, 11);
glColor3f(red * .5, green * .5, blue * .5);
glVertex2i(-1, 9);
glColor3f(red * .8, green * .8, blue * .8);
glVertex2i(1, 9);
}
glEnd();
}
The errors
Error 1 error LNK2019: unresolved external symbol "public: void __cdecl Object::SetValues(int,int,int)" (?SetValues@Object@@QEAAXHHH@Z) referenced in function "public: void __cdecl State::DrawAll(void)" (?DrawAll@State@@QEAAXXZ) C:\Users\Asher\documents\visual studio 2012\Projects\Procedural Terrain\Procedural Terrain\State.obj Procedural Terrain
Error 2 error LNK2019: unresolved external symbol "public: void __cdecl Object::Draw(void)" (?Draw@Object@@QEAAXXZ) referenced in function "public: void __cdecl State::DrawAll(void)" (?DrawAll@State@@QEAAXXZ) C:\Users\Asher\documents\visual studio 2012\Projects\Procedural Terrain\Procedural Terrain\State.obj Procedural Terrain
In a larger class, which does no inherit Object’s functions, uses DrawAll() with a Draw() call in it.
The cpp file and the two respective header files are as follows.
#include "Header.h"
#include "Object.h"
float rotate_z=0;
class State{
private:
std::vector<Object> storage;
public:
State();
State Interpolate(State, State, double);
void Integrate(State,double, const double);
void DrawAll();
void AddObject(Object);
void RemoveObject(int);
};
State::State(){
}
State State::Interpolate(State current,State previous,const double alpha){
//current*alpha + previous * ( 1.0 - alpha );
return current;
}
void State::Integrate(State current, double t, const double dt){
}
void State::AddObject(Object object){
storage.push_back(object);
}
void State::RemoveObject(int tag){
//for(int i=0;i<storage.size;i++){
// if(storage.at(i).getTag==tag){
//storage.erase(storage.begin()+i);
// }
//}
}
void State::DrawAll(void)
{
// reset view matrix
glLoadIdentity();
// move view back a bit
glTranslatef(0, 0, -30);
// apply the current rotation
glRotatef(rotate_z, 0, 0, 1);
rotate_z += 5;
// by repeatedly rotating the view matrix during drawing, the
// squares end up in a circle
int i = 0, squares = 15;
float red = 0, blue = 1;
for (; i < squares; ++i){
Square square;
Object * squareP=□
glRotatef(360.0/squares, 0, 0, 1);
// colors change for each square
red += 1.0/12;
blue -= 1.0/12;
squareP->SetValues(red,0.6,blue);
squareP->Draw();
}
}
The Object header –
#ifndef Object_H
#define Object_H
class Object{
int tag;
public:
void SetValues(int,int,int);
void Draw();
int getTag();
};
class Square: public Object{
int red;
int green;
int blue;
void Draw();
void SetValues(int red2,int green2, int blue2);
};
#endif
Lastly the State header –
#ifndef State_H
#define State_H
#include "Object.h"
#include <vector>
class State{
private:
std::vector<Object> storage;
public:
State();
State Interpolate(State, State, double);
void Integrate(State,double, const double);
void DrawAll();
void AddObject(Object);
void RemoveObject(int);
};
#endif
This is the first C++ project I have worked on and have not fully transferred from a Java background. What could the problem be?
Your
Objectclass has no implementation ofSetValuesfunction. You may want a pure virtual function. Same forDraw.Also note that in C++ functions are not virtual by default. You have to use the
virtualkeyword explicitly in the base class.Also
class Objectseems to be defined at multiple places. Why? Defining it in Object.h would be sufficient.Also please indent your code because it is very hard to read.
Also
std::vector<Object>will not do what you want! Unline Java, where everything is a reference, in C++ things are stored by value in anstd::vectorand therefore your code is subject to the slicing problem. You want to use at lease a pointer there (std::vector<Object*>) but a smart pointer would be even better (std::vector<std::shared_ptr<Object>>)