简体   繁体   中英

C++ Header File Needs a Reference to a Function of Another Class

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=&square;
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?

Nothing is marked as virtual , and I can't see any implementation for Object::Draw() or Object::SetValues().

In C++ to allow a subclass to override a function in the base class, it needs to be marked as virtual (in Java everything is always "virtual").

You can have "abstract" methods (like Java) by saying

class Object {
    public:
        virtual void SetValues(int,int,int) = 0;

Your Object class has no implementation of SetValues function. You may want a pure virtual function. Same for Draw .

class Object {
    virtual void SetValues(int,int,int) = 0;
}

Also note that in C++ functions are not virtual by default. You have to use the virtual keyword explicitly in the base class.

Also class Object seems 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 an std::vector and 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>> )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM