Inheriting a constructor in a .h and .cpp file - c++

So I've got two classes: Object and Player.
I want Player to inherit from Object because Object has basic functions that I need.
Player has it's added-on functions that expand from what Object can do.
I have four files:
Object.cpp, Object.h, Player.cpp, and Player.h.
To make an example out of my situation, I have added a variable to my Player class:
playerVariable. My Object constructor parameters does not contain this, however my Player constructor does, so you can see that Player expands Object.
Anyways, Here is my code:
Object.h:
#include <hge.h>
#include <hgesprite.h>
#include <hgeanim.h>
#include <math.h>
class Object{
int x, y;
HTEXTURE tex;
hgeAnimation *anim;
float angle, FPS, velocity;
public:
Object(int x, int y, HTEXTURE tex, float FPS);
//Setters
void SetX(int x);
void SetY(int y);
void SetSpeed(int FPS); //Image Speed
void SetAngle(float angle); //Image Angle
void SetVelocity(float velocity); //Object Speed/Velocity
//Getters
};
Object.cpp:
/*
** Object
**
*/
#include <hge.h>
#include <hgesprite.h>
#include <hgeanim.h>
#include <math.h>
#include "Object.h"
Object::Object(int x, int y, HTEXTURE tex, float FPS){
this->x = x;
this->y = y;
this->tex = tex;
this->FPS = FPS;
}
//Setters
void Object::SetX(int x){
this->x = x;
}
void Object::SetY(int y){
this->x = x;
}
void Object::SetSpeed(int FPS){
this->FPS = FPS;
anim->SetSpeed(FPS);
}
void Object::SetAngle(float angle){
this->angle = angle;
}
void Object::SetVelocity(float velocity){
this->velocity = velocity;
}
//Getters
Player.h:
#include <hge.h>
#include <hgesprite.h>
#include <hgeanim.h>
#include <math.h>
#include "Object.h"
class Player : public Object{
int playerVariable;
public:
Player(int x, int y, HTEXTURE tex, float FPS, int playerVariable);
//Setters
void SetX(int x);
void SetY(int y);
void SetSpeed(int FPS); //Image Speed
void SetAngle(float angle); //Image Angle
void SetVelocity(float velocity); //Object Speed/Velocity
//Getters
};
Player.cpp:
/*
** Object
**
*/
#include <hge.h>
#include <hgesprite.h>
#include <hgeanim.h>
#include <math.h>
#include "Object.h"
#include "Player.h"
Player::Player(int x, int y, HTEXTURE tex, float FPS, playerVariable){
this->x = x;
this->y = y;
this->tex = tex;
this->FPS = FPS;
}
//Setters
void Object::SetX(int x){
this->x = x;
}
void Object::SetY(int y){
this->x = x;
}
void Object::SetSpeed(int FPS){
this->FPS = FPS;
anim->SetSpeed(FPS);
}
void Object::SetAngle(float angle){
this->angle = angle;
}
void Object::SetVelocity(float velocity){
this->velocity = velocity;
}
//Getters
My problem is, I'm not exactly sure if I'm setting this up right.
I've looked at tutorials on inheritance but I have no idea how to set it up with both
a .h file and a .cpp file for the classes. Can someone help?

You are defining the Object functionality twice. You don't need to define that, it will be inherited from Object and automatically be available on Player.
Your Player constructor needs to invoke the base Object constructor. This is done with constructor initialization lists:
Player::Player(int x, int y, HTEXTURE tex, float FPS, playerVariable)
: Object(x, y, tex, FPS) // forward arguments to base constructor
{}

You can call the base class constructor this way, specifying every parameter :
Player::Player(int x, int y, HTEXTURE tex, float FPS, playerVariable): Object(x, y, tex, FPS) {

It looks like you don't actually need class Player to override SetX(int), SetY(int), SetSpeed(int), SetAngle(float), and SetVelocity(float) of Object. If you did, then you would make these Object member functions virtual.
A few other notes:
You don't need to redefine the Object member functions in Player.cpp. Player is an Object, so it inherits the member functions of class Object. Also, if there are any differences between the implementation in Object.cpp and Player.cpp then you will get linker errors due to a violation of the One Definition Rule.
The Object destructor should be declared virtual.
Rather than setting the members of Object directly in the Player constructor, you could use an initialization list:
Player::Player(int x, int y, HTEXTURE tex, float FPS, playerVariable)
: Object(x, y, tex, FPS), playerVariable(playerVariable)
{
}
Using initialization lists is much more efficient. It is even necessary in this case because Object::x, Object::y, Object::tex, and Object::FPS are all private to Object and friends.
In Object, you should provide a custom copy constructor and copy-assign operator overload (Object::operator=(const Object&)). The C++ compiler provides default implementations of these member functions for you, but because you have pointer members and HTEXTURE members, you likely need to provide explicit implementations to handle the deep copy. The copy constructor and copy-assign overload must always make deep copies.
There is a mismatch on the type of FPS. The Object::FPS member is declared as a float, but the parameter to Object::SetSpeed(int) is an int.

Related

"No matching constructor for initialization of. . ."

I recognize that this type of question has been asked, and I looked at those responses but still think I'm missing something. I get this "No matching constructor error", because I don't have a constructor, but that being said, everything that I looked at about constructors said that you need them if you don't already include the variable names inside the class. But I already did that, so do I need a constructor? If I do, what should it look like then? I'm new to C++, taking a class, and this is for an assignment.
Here's my sensor_node.h file with the class declaration:
#ifndef SENSORNODE_H
#define SENSORNODE_H
#include <iostream>
class LOCATION {
float lat, longi, height;
public:
LOCATION (float lat, float longi, float height);
void setx(float xx);
void sety(float yy);
void setz(float zz);
void print();
};
class SensorNode {
char* NodeName;
int NodeID;
LOCATION Node1;
float batt;
int func;
public:
SensorNode(char *n, float x, float y, float z, int i, float ah);
void print();
void setOK(int o);
int getOK();
void setLOC(float longi, float lat, float h);
};
#endif /* defined(__Project_3__sensor_node__) */
And here's my main.cpp with the error (On the line that says "LOCATION"):
#include <iostream>
using namespace std;
#include "sensor_node.h"
int main() {
LOCATION a; SensorNode s1("Pulse",15.9,-30.1,0,157,2.0);
int hold;
Actually, you so have a constructor: LOCATION (float lat, float longi, float height). Since it is the only one, C++ tries to apply it. However, you did not provide any parameters, thus this constructor does not match.
You have a constructor for LOCATION (why the inconsistent capitalisation, incidentally?) that takes three floats, but the line LOCATION a tries to call the default constructor, which you haven't defined.

calling a function from a class C++

the header file is this:
#include "Lib110ct.h"
class Circle
{
protected:
double mx, my, mdx, mdy, mradius;
public:
Circle(){}
Circle(double x,double y,double dx,double dy,double rad):mx(x),my(y),mdx(dx),mdy(dy),mradius(rad){}
void setPos(double x, double y){mx=x;my=y;}
void setDir(double dx, double dy){mdx=dx; mdy=dy;}
void setRadius(double rad){mradius=rad;}
double getX(){return mx;}
double getY(){return my;}
void draw(Turtle * t);
void clear(Win110ct& win);
void move();
bool collides(Circle & c);
};
#include "shape.h"
int main(int argc, char** argv)
{
Win110ct win;
Turtle * t = win.getTurtle();
Circle Circle;
Circle.setPos(100, 300);
Circle.setRadius(12);
getX();
getY();
Circle.draw(t);
return 0;
}
The error message it's giving me is:
C:\Users\Oluwaseun\Documents\110ct\challenge2\programming\programming\main.cpp|13|undefined reference to `Circle::draw(Turtle*)'|
What am I doing wrong?
You need to define
void draw(Turtle * t);
Please take a look at: http://www.cprogramming.com/declare_vs_define.html
Basically, you define a function when you write the code for it:
void draw(Turtle* t) {
// code here
}

'DrawObject' was not declared in this scope error using std::vector, trying to store class object (c++)

Trying to have my "layer" class, put 3 objects "drawObject", into it's vector, and getting out of scope error.
Everywhere I see they just do "vector >Class< vectorName"; and it works!
layer class:
#include <vector>
#include "DrawObject.h"
using namespace std;
class layer
{
public:
layer();
virtual ~layer();
private:
vector<DrawObject> objects; <--------------- Error here! "'DrawObject' was not declared in this scope"
};
DrawObject class:
#include <SDL/SDL.h>
#include "AnimationSet.h"
class drawObject
{
public:
drawObject(char* name, char* surfaceFile, int xPos, int yPos, int drawLevel, bool willMoveVar, int animationNumber);
drawObject(char* name, char* surfaceFile, int xPos, int yPos, int drawLevel, bool willMoveVar);
virtual ~drawObject();
SDL_Surface* loadImage(char* surfaceFile);
SDL_Surface* getSurface();
void setSurface(SDL_Surface* surface);
char* getName();
void setName(char* name);
int getID();
void setID(int ID);
float getX();
void addX(float xAdd);
void setX(float xSet);
float getY();
void addY(float yAdd);
void setY(float ySet);
bool isSprite();
void setIsSprite(bool isSprite);
bool willMove();
void setWillMove(bool willMove);
bool draw();
void setDraw(bool draw);
private:
SDL_Surface* surface = NULL; // Imagem, no caso de único sprite; caso contrário, spritesheet.
char* name;
int ID;
float xPos;
float yPos;
bool isSpriteVar; // Se isSprite, imagem é spritesheet.
bool willMoveVar;
bool drawVar;
};
vector<DrawObject> should be vector<drawObject>, no? C++ is case-sensitive, you defined the class drawObject but attempt to use DrawObject.

Trouble passing an object as a parameter

Hey I'm trying to pass a class object that I have made into another class to read that data. The error I'm getting is c2061: syntax error: identifier 'Player'
This is my Player2.h
#pragma once
#include "DarkGDK.h"
#include "Input.h"
#include "Player.h"
class Player2{
public:
Player2();
void PlayerSetup();
void PlayerUpdate(Player& user1);
void PlayerHealthReset();
void Gravity();
float GetPosX();
bool CheckMatchEnd();
void PlayerFire(Player& user1);
void PlayerCheckHitEnemies(Player& user1);
private:
float Vx;
float Vy;
float PosX;
float PosY;
float Speed;
int Lives;
int Health;
//
int gravity;
bool playerJumping;
bool matchEnd;
bool playerIsFiring;
float playerBullet;
bool directionBullet;
};
And the error I'm getting is that It can't recognize Player even though I brought in the Player header.
Here is Player.h
class Player{
public:
Player();
void PlayerSetup();
void PlayerUpdate(float PosX2);
void PlayerHealthReset();
float GetPosX();
float GetPosY();
void Gravity();
bool CheckMatchEnd();
void PlayerFire(float PosX2);
private:
float Vx;
float Vy;
float PosX;
float PosY;
float Speed;
int Lives;
int Health;
float playerBullet;
bool playerIsFiring;
int gravity;
bool playerJumping;
bool matchEnd;
bool directionBullet;
};
All the respective code within the header file works 100%, as I've tested it.
player does not compile before player2 is defined, so placing class player above your player2's declaration will compile player BEFORE moving onto player 2.
class player;
class player2{
//...
};
-Also as Hunter McMillen suggested think about making player 2 inherit from a base class, maybe player that defines standard methods all players would use(I dont want to steal hunter's idea, i'll let him post answer about this if he pleases with a more in depth approach).

undefined reference to Base::object linker error # c++ w/ freeglut

I have this code
/////////////////////////////////////Gnome.cpp file
#include "Living.h"
class Gnome:public Living{
private:
public:
Gnome();
void drawObjects();
};
Gnome::Gnome()
{
spriteImg = new Sprite("graphics/gnome.bmp"); //<-------------this is where it says there is the error
loaded = true;
}
///////////////////////////////////Living.h file
#include <iostream>
#include "Sprite.h"
using namespace std;
class Sprite;
class Living{
protected:
int x,y;
static Sprite *spriteImg; //= NULL;
bool loaded;
void reset();
public:
Living();
~Living();
int getX();
void setX(int _x);
int getY();
void setY(int _y);
void virtual drawObjects() =0;
};
// living.cpp
#include "Living.h"
Living::Living()
{
x=y=0;
reset();
}
Living::~Living()
{
delete spriteImg;
}
void Living::setX(int _x)
{
x=_x;
}
int Living::getX()
{
return x;
}
void Living::setY(int _y)
{
y=_y;
}
int Living::getY()
{
return y;
}
void Living::reset()
{
spriteImg = NULL;
loaded = false;
}
// sprite.h
#include <GL/glut.h>
#include <string>
using namespace std;
class ImageLoader;
class Sprite
{
public:
/**
* Enable 2D drawing mode to draw our sprites. This function MUST be called before
* any sprite is drawn on screen using the draw method.
*/
static void enable2D();
/**
* Disables the 2D drawing. This can be called before you are done drawing all 2D
* sprites and want to draw 3D now.
*/
static void disable2D();
Sprite(string filename);
virtual ~Sprite();
virtual void draw();
virtual void drawLiving(int dir, int flag); //flag=1 move
virtual void draw(int X, int Y);
virtual void rotate(GLint degrees);
// getter and setter methods
GLint getAngle() const;
void setAngle(GLint degrees);
void setX(GLdouble x);
void setY(GLdouble y);
GLint getHeight() const;
GLint getWidth() const;
/**
* Sets the pivot point in relation to the sprite itself, that is using the object
* coordiantes system. In this coordiantes system the bottom left point of the object
* is at (0, 0) and the top right is at (1, 1).
*
* E.g. to set the pivot to be in the middle of the sprite use (0.5, 0.5)
* Default values are (1, 1).
* #param pivotX Can be any value, but when x is in the range [0, 1] the pivot is inside the
* sprite where 0 is the left edge of the sprite and 1 is the right edge of the sprite.
* #param pivotY Can be any value, but when y is in the range [0, 1] the pivot is inside the
* sprite where 0 is the bottom edge of the sprite and 1 is the top edge of the sprite.
*/
void setPivot(GLfloat pivotX, GLfloat pivotY);
GLfloat getPivotX() const;
GLfloat getPivotY() const;
GLdouble getX() const;
GLdouble getY() const;
/**
* Sets the pivot to be at the point where object's pivot is set.
* #param obj The reference object to whose pivot we will set this pivot to be.
* Note: if the obj pivot changes or the obj moves after the setPivot call has
* been issued, the pivot of this object will not reflect this changes. You must
* call setPivot again with that object to update the pivot information.
*/
void setPivot(const Sprite &obj);
/**
* Sets the scale of the object. A scale of (1.0, 1.0) means the sprite
* maintains its original size. Values larger than 1 scale the sprite up
* while values less than 1 shrink it down.
*/
void setScale(GLfloat x, GLfloat y);
private:
ImageLoader *image;
GLuint textureID;
GLint angle;
GLdouble x;
GLdouble y;
GLfloat pivotX;
GLfloat pivotY;
GLfloat scaleX;
GLfloat scaleY;
GLint step;
//GLint dir;
//-----------------------------------------------------------------------------
// Initializes extensions, textures, render states, etc. before rendering
//-----------------------------------------------------------------------------
void initScene();
/**
* A helper function taken from http://www.opengl.org/resources/features/OGLextensions/
* to help determine if an OpenGL extension is supported on the target machine at run-time
* #param extension The extension name as a string.
* #return True if extension is supported and false if it is not.
*/
bool isExtensionSupported(const char *extension) const;
};
// if you need the implementation plz let me know
//and finally the engine class
#include <conio.h>
#include "Living.h"
#include "Gnome.h"
using namespace std;
class Engine{
private:
vector<char*> gamemap;
int score;
vector <Living*> gameobjs;
void FindRandomPos(int &x_pos,int &y_pos);
int mapMaxX;
int mapMaxY;
void collisionDetecion(int pX,int pY);
public:
Engine();
void init(const char* mapname="defaultmap.txt",int gnomes=1,int traals=1,int diamonds=10);
void printMap();
void printMap2();
void movePotter();
void calculateScroll();
int getScore();
int getMapMaxX ();
int getMapMaxY ();
};
//and the partial engine.cpp
void Engine::init(const char* mapname,int gnomes,int traals,int diamonds)
{
int i=0;
// int z=0;
mapMaxX=0;
mapMaxY=0;
int x_pos,y_pos;
int countobjs=0;
//gnomes
for(int i=0;i<gnomes;i++)
{
FindRandomPos(x_pos,y_pos);
gameobjs.push_back( new Gnome ); //<---------------here is where the error should begin i think
gameobjs[countobjs]->setX(x_pos);
gameobjs[countobjs]->setY(y_pos);
gamemap[gameobjs[countobjs]->getX()][gameobjs[countobjs]->getY()]='3';
countobjs++;
}
}
so when I try to build it, the linker shows this error: Undefined reference to Living::spriteImg
It is a Linker error, which tells you that the Linker cannot find definition for the static member Living::spriteImg, this is because you just declare it in your class but you never defined it.
You ned to define the static member in your Living.cpp:
Sprite* Living::spriteImg = NULL;
Remember that you need to define it in one and only one .cpp file.
Good Read:
What is the difference between a definition and a declaration?
Living::SpriteImg is a static data member. You have only declared it in the class Living.
However, static data members also needs to be defined separately, preferably in a .cpp file.
// .cpp file
Sprite* Living::spriteImg = 0;