Why does my derived class constructor not work? - c++

I have been working to create an Arduino library to control a touchscreen. My library builds off of pre-existing libraries written to interface with the display & touch controllers.
Here is the constructor that I have been working on:
Display.cpp
Display::Display(int displayCSPin, int displayDCPin, int touchCSPin,
int newBacklightPin, int newRotation, int newBrightness)
: Adafruit_HX8357(displayCSPin, displayDCPin, -1),
Adafruit_STMPE610(touchCSPin)
{
//Initialize display
}
Display.h
#ifndef DISPLAY_H_
#define DISPLAY_H_
#include "arduino.h"
#include "Adafruit_GFX.h"
#include "Adafruit_HX8357.h"
#include "Adafruit_STMPE610.h"
class Display : public Adafruit_HX8357, Adafruit_STMPE610 {
public:
Display(int displayCSPin, int displayDCPin, int touchCSPin,
int newBacklightPin, int newRotation, int newBrightness);
};
Whenever I try to compile, the compiler ignores the variables in the base class constructors, and tries to call a default constructor with no variables:
error: no matching function for call to 'Adafruit_HX8357::Adafruit_HX8357()'
I have tried my best to solve this problem, but have not had any success.
Any and all help is greatly appreciated!
Here is the raw code:
Display.cpp
#include "Display.h"
Display::Display(int displayCSPin, int displayDCPin, int touchCSPin, int newBacklightPin, int newRotation, int newBrightness) : Adafruit_HX8357(displayCSPin, displayDCPin, -1), Adafruit_STMPE610(touchCSPin)
{
// tft = Adafruit_HX8357(displayCSPin, displayDCPin, -1);
//ts = Adafruit_STMPE610(touchCSPin);
tft.begin(HX8357D);
ts.begin();
tft.setRotation(newRotation);
backlightPin = newBacklightPin;
pinMode(backlightPin, OUTPUT);
rotation = newRotation;
backgroundColor = HX8357_BLACK;
brightness = newBrightness;
}
Display.h
#ifndef DISPLAY_H_
#define DISPLAY_H_
#include "arduino.h"
#include "Adafruit_GFX.h"
#include "Adafruit_HX8357.h"
#include "Adafruit_STMPE610.h"
class Display : public Adafruit_HX8357, public Adafruit_STMPE610 {
public:
Display(int displayCSPin, int displayDCPin, int touchCSPin, int newBacklightPin, int newRotation, int newBrightness);
void wake();
void sleep();
bool isAwake();
void setBackGroundColor(int newColor);
int getBackgroundColor();
void setBrightness(int newBrightness);
int getBrightness();
void setRotation(int newRotation);
int getRotation();
bool isTouched();
Adafruit_HX8357 tft;
Adafruit_STMPE610 ts;
int backgroundColor;
private:
int brightness;
int rotation;
int backlightPin;
bool awake;
bool touched;
TS_Point p;
};

Look at the actual constructors available for Adafruit_HX8357 and Adafruit_STMPE610:
Adafruit_HX8357(int8_t _CS, int8_t _DC, int8_t _MOSI, int8_t _SCLK,
int8_t _RST, int8_t _MISO);
Adafruit_HX8357(int8_t _CS, int8_t _DC, int8_t _RST = -1);
Adafruit_STMPE610(uint8_t cspin, uint8_t mosipin, uint8_t misopin, uint8_t clkpin);
Adafruit_STMPE610(uint8_t cs);
Adafruit_STMPE610(void);
Your Display constructor is trying to call the second constructor of each class. However, Display is passing int values where int8_t and uint8_t values are expected. It sounds like maybe your compiler is not performing implicit conversions from int to (u)int8_t, so try using explicit conversions to force it:
Display::Display(int displayCSPin, int displayDCPin, int touchCSPin, int newBacklightPin, int newRotation, int newBrightness)
: Adafruit_HX8357((int8_t)displayCSPin, (int8_t)displayDCPin, -1),
Adafruit_STMPE610((uint8_t)touchCSPin)
{
//Initialize display
}
Otherwise, change you Display constructor parameters to use int8_t and uint8_t instead of int:
Display::Display(int8_t displayCSPin, int8_t displayDCPin, uint8_t touchCSPin, int newBacklightPin, int newRotation, int newBrightness)
: Adafruit_HX8357(displayCSPin, displayDCPin, -1),
Adafruit_STMPE610(touchCSPin)
{
//Initialize display
}

Related

How can I best decouple two classes, which one way dependencies

I am attempting to create a D&D combat encounter simulator using C++ and since it's D&D, all aspects of the simulation are going to depend heavily on the "Dice" Class and its methods.
I could instantiate a "Dice" object every time another class needs
to invoke its methods, however, that would leave everything heavily
coupled and make it very difficult to make changes or extensions later.
I don't have any practical knowledge about things such as Factories, dependency injections, and other such methods.
My question therefore in essence is:
What would be the best way to ensure that the "Dice" class remains as
decoupled as possible from all other classes?
While still enabling them to make use of the "Dice" objects, and its methods, when needed.
Dice.h
#ifndef dice_h_
#define dice_h_
#include <stdlib.h>
class Dice
{
private:
int maxValue;
public:
Dice(int maxValue);
~Dice();
int getMaxValue( void ){return maxValue;}
void setMaxValue(int newMaxValue){maxValue = newMaxValue;}
int rollDice();
int rollMultipleDice(int numberOfDiceRolls);
};
#endif
Dice.cpp
#ifndef dice_cpp_
#define dice_cpp_
#include "dice.h"
Dice::Dice(int maxValue){this->maxValue = maxValue;}
Dice::~Dice(){}
int Dice::rollDice()
{
return (rand() % maxValue) + 1;
}
int Dice::rollMultipleDice(int numberOfDiceRolls)
{
int i = numberOfDiceRolls, sum = 0;
while(i-- > 0)
{
sum += rollDice();
}
return sum;
}
#endif
Actor.h
#ifndef actor_h_
#define actor_h_
#include "dice.h"
class Actor
{
private:
unsigned int hp;
unsigned int ac; // Armor Class
unsigned int dmg;
public:
Actor(unsigned int hp, unsigned int ac, unsigned int dmg);
~Actor();
unsigned int getHP( void );
unsigned int getAC( void );
unsigned int getDmg( void );
void setHP( unsigned int newHP);
void setAC( unsigned int newAC);
void setDmg( unsigned int newDmg);
void attack(Actor* target);
bool isHit(Actor target);
};
#endif
Actor.cpp
#ifndef actor_cpp_
#define actor_cpp_
#include "actor.h"
Actor::Actor(unsigned int hp, unsigned int ac, unsigned int dmg)
{
this->hp = hp;
this->ac = ac;
this->dmg = dmg;
}
Actor::~Actor(){}
unsigned int Actor::getHP( void ){return hp;}
unsigned int Actor::getAC( void ){return ac;}
unsigned int Actor::getDmg( void ){return dmg;}
void Actor::setHP( unsigned int newHP ){this->hp = newHP;}
void Actor::setAC( unsigned int newAC ){this->ac = newAC;}
void Actor::setDmg( unsigned int newDmg ){this->dmg = newDmg;}
void Actor::attack(Actor* target)
{
Dice damageDice(8);
if (isHit(*target))
{
target->setHP(target->getHP() - damageDice.rollDice());
}
}
// helper function to attack function
// do not use elsewhere
bool Actor::isHit(Actor target)
{
Dice atkDice(20);
return atkDice.rollDice() >= target.getAC();
}
#endif
You talk about singletons and the like in the question so do you want ever class that needs to use the dice to use the same instance of the Dice class?
If so since the Dice class doesn't have any states to hold onto it can be a static class. I would then remove the MaxValue and add an input to the RollDice and RollMutiDice to take a Max Value (which I am guessing is suppose to the "sides" of the dice). So a call to Dice::RollDice(3) is to roll a 3 sided dice or Dice::RollMutiDice(6,3) would roll a 6 sided dice 3 times.
Also make sure you send the rand() class. I think is it srand(int). Usually you pass it time so it is fairly random

Error: some class is not a template

I have a header file Algo.h. It has the following content:
#include <iostream>
#include <fstream>
#include <math.h>
#include <float.h>
#include <string.h>
#include <stdlib.h>
using namespace std;
//some static functions
// ...
template <class Type> class Algo{
int
public:
Algo(int size, int num, int plth, int theN, float** theAg, int theLN,
float* theIn, float theeEps = 1E-3, float theEpsilonLR = 1E-3,
int theCycle = 30, bool DebInf = false, int theT = -1, int** theX = 0,
const char* theFileName = 0, const char* theFileNameChar = 0);
~Algo();
//some methods
//...
};
//Constructor
template <class Type> Algo<Type>::Algo(int size, int num, int plth, int theN, float** theAg, int theLN,
float* theIn, float theeEps = 1E-3, float theEpsilonLR = 1E-3,
int theCycle = 30, bool DebInf = false, int theT = -1, int** theX = 0,
const char* theFileName = 0, const char* theFileNameChar = 0){
//...
}
// ...
Then I'd like to usel it in main.cpp:
#include "Algo.h"
#include <float.h>
#include <time.h>
#include <stdlib.h>
#include <string>
#include <iostream>
using namespace std;
Algo<int>* construct1(const int & rt, float** & rm); //error: Algo is not a template
Algo<int>* construct2(const int & rte, float** & rm, Algo<int>* & the1, const bool & rob1); //error: Algo is not a template
//...
int main(){
//...
return 0;
}
It seems that everything should work fine, but I always get this error:
Algo is not a template.
Do you have any ideas how to fix it?
there is "int" which should not be there in your code. delete it, please.
template <class Type> class Algo{
int // here should be deleted
public:
...
constructor of Algo has many default params, but when you define this function, these default params should not be set value in param-list. you can make the constructor definition as follows:
template <class Type> Algo<Type>::Algo(int size, int num, int plth, int theN, float** theAg, int theLN, float* theIn, float theeEps, float theEpsilonLR, int theCycle, bool DebInf, int theT, int** theX, const char* theFileName, const char* theFileNameChar)
{
//...
}
do these 2 fixs, it will works.( I have try it on my computer~ )
I don't think this is the only problem, but pay attention to how you attempt to use it.
The constructor:
Algo(int size, int num, int plth, int theN, float** theAg, int theLN,
float* theIn, float theeEps = 1E-3, float theEpsilonLR = 1E-3,
int theCycle = 30, bool DebInf = false, int theT = -1, int** theX = 0,
const char* theFileName = 0, const char* theFileNameChar = 0);
Has many parameters. The first 7 are required, the remainder have default values and are optional. However, when you try and instantiate an instance:
Algo<int>* construct1(const int & rt, float** & rm); //error: Algo is not a template
Algo<int>* construct2(const int & rte, float** & rm, Algo<int>* & the1, const bool & rob1); //error: Algo is not a template
You are passing either 2, or 4 parameters. There is no matching overload.
You need to provide at least the first 7 parameters.

Object is wrong type

Basically for some reason new object is wrong type. All source code is on github https://github.com/teuro/sfml-radar. If it's help please fork at will.
I have following class:
#ifndef _VIEW_HPP
#define _VIEW_HPP
#include <iostream>
#include "sfml_drawsurface.hpp"
class View {
protected:
View(Drawsurface& d) : drawer(d) {
std::clog << "View::View()" << std::endl;
}
Drawsurface& drawer;
virtual void draw() = 0;
};
#endif
That is base class for all different kind of views. Now I have derived sub-class
#ifndef _GAME_VIEW_HPP
#define _GAME_VIEW_HPP
#include <vector>
#include <iostream>
#include <typeinfo>
#include "view.hpp"
#include "../models/game.hpp"
class Gameview : public View {
public:
Gameview(Drawsurface& d);
~Gameview();
void draw();
private:
Drawsurface& drawer;
};
#endif // _GAME_VIEW_HPP
Then abstract class Drawsurface
/**
* drawsurface base for all graphics pure abstract
* provide only interface quite high-level
* 2014/06/02
* Juha Teurokoski
**/
#ifndef _DRAWSURFACE_HPP
#define _DRAWSURFACE_HPP
#include <string>
#include "../models/point.hpp"
class Drawsurface {
public:
bool font_loaded;
virtual void rectangleColor(Point& a, Point& b, unsigned int color) = 0;
virtual void lineColor(Point& a, Point& b, unsigned int color) = 0;
virtual void circleColor(Point& a, unsigned int rad, unsigned int color) = 0;
virtual void trigonColor(Point& a, Point& b, Point& c, unsigned int color) = 0;
virtual void trigonColor(Point& a, unsigned int size, unsigned int color) = 0;
virtual void load_font(std::string font) = 0;
virtual void draw_picture(std::string tiedosto, Point& a, bool center = false) = 0;
virtual void draw_text(std::string text, Point& a, unsigned int color = 0) = 0;
virtual int get_fontsize() = 0;
virtual void flip() = 0;
virtual void clear_screen() = 0;
virtual ~Drawsurface() { }
};
#endif
Now if I create new instance of sfml_drawsurface which is sub-class of Drawsurface. For some reason new object is Drawsuface istead of sfml_drawsurface. Below is sfml_drawsurface class.
#ifndef SFML_DRAWSURFACE_HPP
#define SFML_DRAWSURFACE_HPP
/**
* sfml-drawsurface provides basic drawing, pictures and text
* require drawsurface
* 2014/06/02
* Juha Teurokoski
**/
#include "drawsurface.hpp"
#include <vector>
#include <stdexcept>
#include <iostream>
#include <SFML/Graphics.hpp>
class sfml_drawsurface : public Drawsurface {
public:
sfml_drawsurface(sf::RenderWindow& window);
~sfml_drawsurface();
void rectangleColor(Point& a, Point& b, unsigned int color);
void circleColor(Point& a, unsigned int rad, unsigned int color);
void lineColor(Point& a, Point& b, unsigned int color);
void trigonColor(Point& a, Point& b, Point& c, unsigned int color);
void trigonColor(Point& a, unsigned int _size, unsigned int color);
void draw_picture(std::string tiedosto, Point& a, bool center = false);
void draw_text(std::string text, Point& a, unsigned int color);
void load_font(std::string font);
void clear_screen();
int get_fontsize();
void flip();
protected:
private:
sf::RenderWindow& window;
sf::Font font;
sf::Color active;
sf::Color normal;
};
#endif // SFML_DRAWSURFACE_HPP
I create new object like this:
sfml_drawsurface drawer(window);
this->gameview = new Gameview(drawer);
std::clog << typeid(drawer).name() << std::endl;
And everything seems to be right, because std::clog outout is '16sfml_drawsurface'.
Next place is draw-method then happens something really weird.
Same print is now '11Drawsurface'.
Looks like Mike had the right idea. From your Program.cpp file you have in your constructor:
Program::Program() {
Game game;
...
this->gamecontroller = new Gamecontroller(game); //Probably also bad
sfml_drawsurface drawer(window);
this->gameview = new Gameview(drawer);
}
The problem is that drawer ceases to exist once the constructor is finished leaving you with a dangling reference and undefined behaviour. Looks like you may have the same problem with the game variable.
Solution is to not have them as local variables but as either class members (preferred) or dynamically allocated (it depends how long you need to have them around).

Way around "first defined here" error?

I need to have two alternate classes with the same name, that I can switch between each other by simply changing which class is included in main.
For example;
Mode_1.h
class Draw{
private:
// private stuff
public:
void Render(int x, char y);
};
Mode_2.h
class Draw{
private:
// private stuff
public:
void Render(int x, char y);
};
main.cpp
#include "Mode_1.h"
int main(){
Draw D;
int x = 2;
char y = 'x';
D.Render(x, y);
}
Currently I'm having to comment out the .h and .cpp files I'm not using to avoid the "first defined here" error. What I want is that all I have to do to switch between them is change
#include "Mode_1.h"
to
#include "Mode_2.h"
You should put them in different namespaces:
namespace Mode2
{
class Draw{
private:
// private stuff
public:
Draw(int x, char y);
};
}
In main you can then select the namespace you want to use:
#include "Mode_1.h"
#include "Mode_2.h"
using namespace Mode2;
int main()
{
Draw D;
int x = 2;
char y = 'x';
D.Draw(x, y);
return 0;
}
You may try like this:
#ifdef MODE1
#include "Mode_1.h"
#else
#include "Mode_2.h"
#endif
int main(){
Draw D;
int x = 2;
char y = 'x';
Draw(x, y);
}
And compile this source file with -DMODE1 or none depending on you wish to include Mode_1.h or Mode_2.h

C++ Expected type-specifier before 'XY' - In member function virtual void

I work on my project (game in C++) and I found this error.
"Expected type-specifier before 'Clovek'
In member function virtual void"
This error is show for all - Clovek, PlatoveBrneni, ObourucniMec, BronzovyPrsten, LektvarCloveci.
For this project I use design pattern - builder.
Thanks for all replies!
Here are codes:
CloverBuilder.h
#ifndef CLOVEK_BUILDER_H
#define CLOVEK_BUILDER_H
#include <iostream>
#include "HrdinaBuilder.h"
#include "Rasa.h"
#include "Brneni.h"
#include "Zbran.h"
#include "Prsten.h"
#include "Lektvar.h"
using namespace std;
namespace LordOfDragonV2 {
class ClovekBuilder : LordOfDragonV2::HrdinaBuilder {
public:
void buildRasa(string nazevRasy, int silaRasy, int odolnostRasy, int inteligenceRasy, int pocetZivotaRasy, string popisRasy);
void buildBrneni(string nazevBrneni, int bonusOdolnosti, int bonusZivota);
void buildZbran(string nazevZbrane, int bonusSily, int bonusZivota);
void buildPrsten(string nazevPrstenu, int bonusInteligence, int bonusZivota);
void buildLektvar(string nazevLektvaru, int bonusSily, int bonusOdolnosti, int bonusInteligence, int bonusZivota);
};
}
#endif //CLOVEK_BUILDER_H
ClovekBuilder.cpp
#include "ClovekBuilder.h"
void LordOfDragonV2::ClovekBuilder::buildRasa(string nazevRasy, int silaRasy, int odolnostRasy, int inteligenceRasy, int pocetZivotaRasy, string popisRasy) {
m_hrdina->setRasa( new Clovek(nazevRasy, silaRasy, odolnostRasy, inteligenceRasy, pocetZivotaRasy, popisRasy) );
}
void LordOfDragonV2::ClovekBuilder::buildBrneni(string nazevBrneni, int bonusOdolnosti, int bonusZivota) {
m_hrdina->setBrneni(new PlatoveBrneni(nazevBrneni, bonusOdolnosti, bonusZivota));
}
void LordOfDragonV2::ClovekBuilder::buildZbran(string nazevZbrane, int bonusSily, int bonusZivota) {
m_hrdina->setZbran(new ObourucniMec(nazevZbrane, bonusSily, bonusZivota));
}
void LordOfDragonV2::ClovekBuilder::buildPrsten(string nazevPrstenu, int bonusInteligence, int bonusZivota) {
m_hrdina->setPrsten(new BronzovyPrsten(nazevPrstenu, bonusInteligence, bonusZivota));
}
void LordOfDragonV2::ClovekBuilder::buildLektvar(string nazevLektvaru, int bonusSily, int bonusOdolnosti, int bonusInteligence, int bonusZivota) {
m_hrdina->pridejLektvar(new LektvarCloveci(nazevLektvaru, bonusSily, bonusOdolnosti, bonusInteligence, bonusZivota));
}
You did not show where Clovek is declared. It is obvious that the compiler also does not see the corresponding declaration (and definition) of Clovek
You should include the header where this type is declared or/and defined.
For excample in this function you are trying to create an object of type Clovek using operator new:
void LordOfDragonV2::ClovekBuilder::buildRasa(string nazevRasy, int silaRasy, int odolnostRasy, int inteligenceRasy, int pocetZivotaRasy, string popisRasy) {
m_hrdina->setRasa( new Clovek(nazevRasy, silaRasy, odolnostRasy, inteligenceRasy, pocetZivotaRasy, popisRasy) );
}
Or maybe you need to use a qualified name for example LordOfDragonV2::Clovek instead of Clovek