I want to put two clasess in one header file. The one is a base class and the second is derived form this base class, what I mean is something like this:
class Drawable{
public:
Drawable();
void setPosition(math::Vector3 position);
void draw();
};
class Box: public Drawable{} ;
But I get error "undefined reference to `Drawable::Drawable()' ". In source file I have:
class Drawable {
public:
math::Vector3 position;
math::Vector3 rotation;
Drawable() {
position = math::Vector3(1.0, 1.0, 1.0);
rotation = math::Vector3(0.0, 0.0, 0.0);
}
void setPosition(math::Vector3 position) {
this->position = position;
}
void draw() {
}
};
class Box: public Drawable {
public:
void draw() {
glBegin(GL_TRIANGLES);
drawPoint(this->position + math::Vector3(1.0f, 1.0f, 1.0f));
drawPoint(this->position + math::Vector3(-1.0f, 1.0f, 1.0f));
drawPoint(this->position + math::Vector3(-1.0f, 1.0f, 1.0f));
drawPoint(this->position + math::Vector3(1.0f, 1.0f, 1.0f));
drawPoint(this->position + math::Vector3(1.0f, 1.0f, -1.0f));
drawPoint(this->position + math::Vector3(1.0f, -1.0f, 1.0f));
glEnd();
}
};
So it seems to me impossible to accomplish this because the derivated class in header not already knows about the constructor of the base class. Am I right?
You need to do something like this:
example.h
class Drawable
{
public:
Drawable();
void setPosition(math::Vector3 position);
virtual void draw();
math::Vector3 position;
math::Vector3 rotation;
};
class Box: public Drawable
{
public:
virtual void draw();
};
example.cpp
#include "example.h"
Drawable::Drawable() {
position = math::Vector3(1.0, 1.0, 1.0);
rotation = math::Vector3(0.0, 0.0, 0.0);
}
void Drawable::setPosition(math::Vector3 position) {
this->position = position;
}
void Drawable::draw() {
}
void Box::draw() {
glBegin(GL_TRIANGLES);
drawPoint(this->position + math::Vector3(1.0f, 1.0f, 1.0f));
drawPoint(this->position + math::Vector3(-1.0f, 1.0f, 1.0f));
drawPoint(this->position + math::Vector3(-1.0f, 1.0f, 1.0f));
drawPoint(this->position + math::Vector3(1.0f, 1.0f, 1.0f));
drawPoint(this->position + math::Vector3(1.0f, 1.0f, -1.0f));
drawPoint(this->position + math::Vector3(1.0f, -1.0f, 1.0f));
glEnd();
}
Header defines:
- Constructor/Destructor signatures
- Member variables
- Member function signatures
Source defines
- Constructor/Destructor implementation
- Member function implementation
Note: Use a scope resolution operator ::
to refer to the class members.
- All data members (like
math::Vector3 position;
) MUST be defined ONLY in the header file, NOT in the cpp.
- The definition of a method in the cpp file is:
return_type class_name::function_name (parameters) { ... }
draw
should be virtual
in your case. Even, maybe, pure virtual (like void draw() = 0;
in the base class and declared and implemented in the derived).
Example:
///////////////////////////////////////////
// header
class A
{
public:
A();
void f();
private:
int x;
};
///////////////////////////////////////////
// cpp
A::A()
{
/* constructor impl */
}
void A::f()
{
/* impl */
}
You would implement your methods in the source file like this:
void Drawable :: setPositon(...){ //do stuff };
You are declaring a new class with the same name than in the header!
also, seeing as you have a setter function for your position
member, you should probably make it private, and declare & define a getter as well:
class Drawable{
private:
math::Vector3 position;
math::Vector3 rotation;
public:
Drawable();
void setPosition(math::Vector3 position);
math::Vector3 getPosition();
void setRotation(math::Vector3 rotation);
math::Vector3 getRotation();
void draw();
};
with your current implementation, calling the setter would be somewhat redundant, as you could just access the member directly instead of using a setter function:
Drawable d;
d.position = math::Vector3(0,0,0); //both do the
d.setPosition(math::Vector3(0,0,0)); //same thing