C++ public inheritance [SFML] - c++

I've been having trouble drawing a sprite of hero to the screen(which I solved with a different approach). Problem was caused because of inheritance. Now I'm gonna put all the code and tell the story alongside with codes.
Character.h (the parent class for hero and npcs)
#pragma once
#include <SFML/Graphics.hpp>
#include "TextureHolder.h"
using namespace sf;
using namespace std;
class Character
{
protected:
Vector2f m_Position;
int m_Speed;
public:
Character();
void spawn(int x, int y, string direction);
Sprite m_Sprite;
Texture m_Texture;
void virtual update(float elapsedTime);
};
Character.cpp has nothing except constructor and update function declerations
#include "stdafx.h"
#include "Character.h"
Character::Character(){}
void Character::update(float elapsedTime) {}
Hero.h
#pragma once
#include "Character.h"
using namespace sf;
using namespace std;
class Hero : public Character
{
private:
public:
Hero();
void virtual update(float elapsedTime);
};
And finally Hero.cpp
#include "stdafx.h"
#include "Hero.h"
Hero::Hero()
{
m_Texture = TextureHolder::GetTexture("images/chars/hero.png");
m_Sprite.setTexture(m_Texture);
}
void Hero::update(float elapsedTime)
{
}
With the classes this way, When I try to draw hero.m_Sprite it gives access violation.
As you see I'm using public inheritance from character to hero(which should have worked perfectly, since when I type "hero." it shows me list of it's public members and m_sprite is among them)
But when I try to add m_Sprite and m_Texture in Hero.h(instead of inheriting them from Character class , I got no errors.
What is the reason behind this?
Edit: draw.cpp
#include "stdafx.h"
#include "Engine.h"
void Engine::draw()
{
m_Window.clear(Color::Black);
m_Window.setView(m_MainView);
m_Window.draw(hero.m_Sprite);
m_Window.display();
}
EDIT 2: IT doesn't give errors anymore. I didn't change anything and I don't have any idea what caused and what fixed the problem.

Related

"Attribute is protected within this context" with inheritance and .h and .cpp files

I'm trying to code a game with Irrlicht, but I got stuck with this problem meanwhile I was separating the code into .h and .cpp files.
The main error in the compiler is 'node is protected within this context".
Node is an attribute of "GameObjectOverworld", and was invoked from "Player" (GameObjectOverworld child class)
This worked fine until I separated the code in .h and .cpp files.
The GameObjectOverworld.h
#ifndef __GAMEOBJECTOVERWORLD_H__
#define __GAMEOBJECTOVERWORLD_H__
#include <irrlicht.h>
#include <stdio.h>
#include "GameObject.h"
class GameObjectOverWorld : public GameObject{
protected:
scene::ISceneNode* node = nullptr;
public:
GameObjectOverWorld() {}
core::vector3df getPosition(){return node->getPosition();}
};
#endif
The player.h
#ifndef __PLAYER_H__
#define __PLAYER_H__
#include <irrlicht.h>
#include <stdio.h>
#include "GameObject.h"
#include "GameObjectOverworld.h"
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
class Player : public GameObjectOverWorld{
private:
std::string name ="";
float speed = 15.0f;
public:
Player() = default;
void addPlayerModel(ISceneManager* smgraux, IVideoDriver* driveraux){}
void move (char axis, int direction, float frameDeltaTime){}
};
#endif
And player.cpp (the one which sends the error)
#include "Player.h"
void addPlayerModel(ISceneManager* smgraux, IVideoDriver* driveraux){
Player::node = smgraux->addCubeSceneNode(10.0f, 0, 0, core::vector3df(15.0f, 0.0f, 45.0f), core::vector3df(0, 0, 0), core::vector3df(1.0f, 1.0f, 1.0f));
if (node)
{
node->setMaterialTexture(0, driveraux->getTexture("Materials/madero.jpg"));
node->setMaterialFlag(video::EMF_LIGHTING, false);
}
}
You forgot to link the method addPlayerModel to the class:
Change:
void addPlayerModel(ISceneManager* smgraux, IVideoDriver* driveraux)
To
void Player::addPlayerModel(ISceneManager* smgraux, IVideoDriver* driveraux)
Also change Player::node to this->node because your 'node' attribute is not static.

Access by "a pointer of the base class" to a method or attribute of the child class which was not declared in the base class(dynamically)

during one of our assignments in C++ programming ( Inheritance), I had to design an abstract class Shape with some attributes like color, rotate degree and etc, Which are common between shapes. However, during the implementation of Base classes like Circle, Rectangle and ... I had to add some attributes like Center of the circle (which it self-required its own setter and getter cause it's private ! ) or 4 corners of the rectangle (with its setter and getter ) which were not mentioned as a function(whether virtual or not) in out Base class.
Originally I wanted to have access to every method of derived class using a pointer of the base class.In my main, I used a Pointer of my base class, Shape * to have a Dynamic Bind to the common methods and attributes, but when it comes to setting the separate (uncommon between derived and base) attributes, it's not accessible via Pointer of the base class. I tried to declare them as virtual functions in my Base class, however, it doesn't work and it's also illogical, as the user might have many characteristics in one shape!
Does any one have any idea how can this problem be solved?
and how can I have access to those mentioned methods and attributes that are only declared in the Derived class, using Shape*?
tnx
this is my base class for shapes.
class Shape
{
public:
virtual void set_color(int color)=0;
virtual void set_border_color(int border_color)=0;
virtual void set_degree(float border_width)=0;
virtual void set_border_width(double rotate_degree)=0;
virtual void set_opacity(double opacity)=0;
protected:
int color;
int border_color;
float border_width;
double rotate_degree;
double opacity;
};
respectively are my Circle and Rectangle class
circle Header:
#ifndef CIRCLE_H
#define CIRCLE_H
#include "shape.h"
class Circle :public Shape
{
public:
void set_color(int _color);
void set_border_color(int _border_color);
void set_degree(float rotate_degree);
void set_border_width(double border_width);
void set_opacity(double _opacity);
virtual void set_x_center(int _x_center);
virtual void set_y_center(int _y_center);
virtual void set_radius(int _radius);
virtual void set_name(std ::string _name);
int get_color();
int get_x_center();
int get_y_center();
std::string get_name();
private:
int x_center;
int y_center;
int radius;
std ::string name;
};
#endif // CIRCLE_H
circle CPP:
#include <sstream>
#include <iostream>
#include <algorithm>
#include <string>
#include "circle.h"
#include "shape.h"
void Circle::set_color(int _color){ color=_color;}
void Circle::set_border_color(int _border_color){border_color=_border_color;}
void Circle::set_degree(float _rotate_degree){rotate_degree=_rotate_degree;}
void Circle::set_border_width(double _border_width){border_width=_border_width; }
void Circle::set_opacity(double _opacity){opacity=_opacity;}
int Circle::get_color(){return color;}
void Circle::set_x_center(int _x_center){ x_center=_x_center;}
void Circle::set_y_center(int _y_center){ y_center=_y_center;}
void Circle::set_radius(int _radius){ radius=_radius;}
void Circle::set_name(std ::string _name){ name=_name;}
int Circle::get_x_center(){return x_center;}
int Circle::get_y_center(){return y_center;}
std::string Circle::get_name(){return name;}
rectangle HEADER:
#ifndef RECT_H
#define RECT_H
#include <sstream>
#include <iostream>
#include <algorithm>
#include <string>
#include "rect.h"
#include "shape.h"
class Rect : public Shape
{
public:
void set_color(int _color);
void set_border_color(int _border_color);
void set_degree(float _border_width);
void set_border_width(double _rotate_degree);
void set_opacity(double _opacity);
void set_first_point(int _first_x,int _first_y);
void set_second_point(int _second_x,int _second_y);
void set_name(std ::string _name);
private:
int first_point [2];
int second_point [2];
std ::string name;
};
#endif // RECT_H
rectangle CPP:
#include "rect.h"
#include "shape.h"
void Rect::set_color(int _color){ color=_color;}
void Rect::set_border_color(int _border_color){border_color=_border_color;}
void Rect::set_degree(float _border_width){border_width=_border_width;}
void Rect::set_border_width(double _rotate_degree){rotate_degree=_rotate_degree;}
void Rect::set_opacity(double _opacity){opacity=_opacity;}
void Rect::set_first_point(int _first_x,int _first_y){first_point[0]=_first_x;first_point[1]=_first_y;}
void Rect::set_second_point(int _second_x,int _second_y){second_point[0]=_second_x;second_point[1]=_second_x;}
void Rect::set_name(std ::string _name){name=_name;}
and here is my main
#include <cstdlib>
#include <vector>
#include <cmath>
#include <string>
#include <vector>
#include <cmath>
#include <sstream>
#include <iostream>
#include <algorithm>
#include "shape.h"
#include "circle.h"
using namespace std;
int main()
{
Circle a;
Shape* b;
b=&a;
b->set_color(12);
b->set_x_center(30);
cout<< b->get_x_center();
return 0 ;
}
Originally I wanted to have access to every method of derived class using a pointer of the base class.
You can do so by dynamic casting back to the Circle *:
b->set_color(12);
dynamic_cast<Circle *>(b)->set_x_center(30);
std::cout << dynamic_cast<Circle *>(b)->get_x_center();
This works already, however, when dynamic casting like this make sure the result is not a nullptr
b->set_color(12);
Circle *c = dynamic_cast<Circle *>(b);
if (c != nullptr)
{
c->set_x_center(30);
std::cout << c->get_x_center();
}

Basic error of seperate class in polymorphism. C++

Aaand im back again with my second question and im kinda not sure about wether i should have posted all the seperate classes cuz it looks somewhat long. And im sure the solution is pretty small.
Anyways, i am at polymorphism tutorial vid that i am following and everything works fine if i follow it and put all classes in "main.cpp". But when i tried to do the same program with seperate classes (seen below) i am getting error "
E:\Codeblocks\Poly\main.cpp|11|error: cannot convert 'Ninja' to 'Enemy*' in initialization|".*
I kinda understand what the error is saying..i think.. but dont know what i did wrong since the same code was working when Enemy and Ninja class wasnt seperate but now as seperate classes its not working. I think i included those classes properly in main.cpp.
main.cpp
#include <iostream>
#include "Enemy.h"
#include "Ninja.h"
#include "Monster.h"
int main()
{
Ninja n;
Monster m;
Enemy *enemy1=&n;
Enemy *enemy2=&m;
enemy1->setAttackPower(20);
enemy2->setAttackPower(50);
n.attack();
m.attack();
return 0;
}
Enemy.h
#ifndef ENEMY_H
#define ENEMY_H
class Enemy
{
public:
Enemy();
void setAttackPower(int a);
protected:
int attackPower;
private:
};
#endif // ENEMY_H
Enemy.cpp
#include "Enemy.h"
Enemy::Enemy()
{
//ctor
}
void Enemy::setAttackPower(int a)
{
attackPower=a;
};
Ninja.h
#ifndef NINJA_H
#define NINJA_H
class Ninja
{
public:
Ninja();
void attack();
protected:
private:
};
#endif // NINJA_H
Ninja.cpp
#include "Ninja.h"
#include <iostream>
Ninja::Ninja()
{
//ctor
}
void Ninja::attack(){
std::cout<<" I am a ninja. Ninja chop! -"<<attackPower<<"\n";}
This is because your Ninja class is not inhereted from Enemy class. You must define Ninja class like this:
#include "Enemy.h"
class Ninja : public Enemy
{
public:
Ninja();
void attack();
protected:
private:
};
EDIT: I added #include directive. Without it compiler won't know, where to find Enemy class declaration.

sharing an object with multiple classes

I have 3 classes namely Board, Game, and AI
i want to have the object chessBoard of Board class to be use by Game and AI, and also by the Board Class. I want them to access that single chessBoard object (sharing)
problem is, it gives me the infamous fatal error LNK1169: one or more multiply defined symbols found. Also, there are Board.h,Game.h and AI.h (only declarations in them), and i also have their corresponding .cpp files. Each .h files have guards included (#ifndef _XXXXXX_H_)
I tried to include Board chessBoard inside Board.h file (just below the class), and it seems guards are not working.
Error 7 error LNK2005: "class Board chessBoard" (?chessBoard##3VBoard##A) already defined in AI.obj C:\Users\xxxx\Documents\Visual Studio 2010\Projects\CHESSv3\CHESSv3\Board.obj CHESSv3
Error 8 error LNK2005: "class Board chessBoard" (?chessBoard##3VBoard##A) already defined in AI.obj C:\Users\xxxxx\Documents\Visual Studio 2010\Projects\CHESSv3\CHESSv3\Game.obj CHESSv3
Error 9 error LNK2005: "class Board chessBoard" (?chessBoard##3VBoard##A) already defined in AI.obj C:\Users\xxxxx\Documents\Visual Studio 2010\Projects\CHESSv3\CHESSv3\ProgramEntryPoint.obj CHESSv3
AI.h
#ifndef _AI_H_
#define _AI_H_
#include <iostream>
#include <string>
using namespace std;
struct node {
string position;
string nextPosition;
float score;
int level;
float totalscore;
node* up;
node* right;
node* left;
bool approved;
string move;
};
class AI {
private:
//string board;
//string board[8][8];
int score1;
int maxscore;
int totalscore;
public:
void GetBoard(string[][8]);
void AnalyzeMyPositions();
void ExecuteAdvanceHeuristicMove();
};
#endif
Game.h
#ifndef _GAME_H_
#define _GAME_H_
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
#include <queue>
#include <stack>
#include <cmath>
using namespace std;
class Game {
public:
char WhosTurn();
bool Playable();
bool GetMoveFromPlayer();
void TurnOver();
Game();
private:
char turn;
};
#endif
Board.h
#ifndef _BOARD_H_
#define _BOARD_H_
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
#include <queue>
#include <stack>
#include <cmath>
using namespace std;
class Board {
public:
bool SquareChecker(string);
bool MoveChecker(string);
Board();
void PrintBoard();
int Execute(string);
void UnExecute();
string CB[8][8];
private:
char turn;
vector<string> BoardRecord;
stack<string> CBR;
//string CB[8][8];
};
Board chessBoard;
#endif
If you really want to do this, you need to make the declaration of the object extern in the header Board.h:
extern Board chessBoard;
You then provide a declaration in Board.cpp:
Board chessBoard;
Much better, though would be to create it in enclosing code and pass it (by reference) to the constructors of the other classes.
What you are looking for is the Singleton design pattern which can achieved in the following way:
// Board.h
class Board {
private:
static instance_;
public:
static Board *instance();
}
// Board.cpp
Board *Board::instance_ = NULL;
Board *Board::instance() {
if (!instance_)
instance_ = new Board();
return instance_;
}
Mind that this pattern can either be seen as good or bad, if you don't like using it you should consider passing the reference of an instantiated Board class to all the requiring ones and keep it stored in each object as an instance variable. Something like:
Game::Game() {
this->board = new Board();
this->ai = new AI(board);
// or better this->ai = new AI(this) so AI can access all game methods
}
Your problem could be that there could be 3 different chessBoard definitions because you might be adding 3 different #include "Board.h". Please make only a single object at a place where you have more control rather than creating it globally inside Board.h
Did you try it like this? Include the necessary include declarations only in the .cpp files.
//Board.h
class Board {};
//Game.h
class Board;
class Game {
Board* myBoard;
public:
void setBoard(Board*);
};
//AI.h
class Board;
class AI {
Board* myBoard;
public:
void setBoard(Board*);
};
void main() {
Board chessBoard;
Game g;
g.setBoard(&chessBoard);
AI ai;
ai.setBoard(&chessBoard);
}

unknown type error in C++

What is going on?
#include "MyClass.h"
class MyOtherClass {
public:
MyOtherClass();
~MyOtherClass();
MyClass myVar; //Unknown type Error
};
Suddenly when I include the .h and write that var Xcode gives me tons of errors... and also the unknown type error.
How can it be unknown when the .h is included right there?
Here is the NodeButton.h file which would correspond to the MyClass.h in the example
#pragma once
#include "cinder/Vector.h"
#include "cinder/gl/gl.h"
#include "cinder/gl/Texture.h"
#include "cinder/Color.h"
#include "cinder/ImageIo.h"
#include "cinder/Timeline.h"
#include "cinder/app/AppBasic.h"
#include "cinder/App/App.h"
#include "Node.h"
#include "CursorMano.h"
using namespace ci;
using namespace ci::app;
using namespace std;
using namespace is;
typedef boost::shared_ptr<class NodeButton> NodeButtonRef;
class NodeButton : public Node2D
{
public:
NodeButton (CursorMano *cursor, string imageUrl, bool fadeIn = false, float delay = 0.0f);
virtual ~NodeButton ();
//methods
void update( double elapsed );
void draw();
void setup();
//events
bool mouseMove( ci::app::MouseEvent event );
//vars
CursorMano *mCursor;
gl::Texture mImageTexture;
Anim<float> mAlpha = 1.0f;
bool mSelected = false;
private:
};
And here are the contents of CursorMano.h which would correspond to MyOtherClass.h in the example.
#pragma once
#include <list>
#include <vector>
#include "cinder/app/AppBasic.h"
#include "cinder/qtime/QuickTime.h"
#include "cinder/gl/Texture.h"
#include "cinder/Vector.h"
#include "NodeButton.h"
using namespace ci;
using namespace ci::app;
using namespace std;
class CursorMano {
public:
CursorMano (AppBasic *app);
~CursorMano ();
void mueveMano(Vec2i);
void update();
void draw();
void play(int button);
void reset(int button);
Vec2i mMousePos;
NodeButton mButtonCaller; //this gives the unknow type error
private:
AppBasic *mApp;
gl::Texture mFrameTexture;
qtime::MovieGl mMovie;
int mIdButton;
};
You have a circular dependency of your header files.
NodeButton.h defines NodeButton class which CursorMano.h needs to include so that compiler can see definition for NodeButton but NodeButton.h itself includes CursorMano.h.
You will need to use forward declarations to break this circular dependency.
In NodeButton.h you just use an pointer to CursorMano so You do not need to include the CursorMano.h just forward declare the class after the using namespace declarations.
using namespace std;
using namespace is;
class CursorMano;
It's probably a result of the circular dependency between you two header files (NodeButton includes CursorMano and CursorMano includes NodeButton). Try removing the #include "CursorMano.h" in NodeButton.h and add class CursorMano; before your NodeButton declaration.