Arduino: Inheritance and arrays of pointer subclasses - c++

This is problem #2 from this previous question:
Inheritance in Arduino Code
Building off of Steven's answer, I do need the array that holds the pointers to persist outside of its scope, which is resulting in some weird behavior.
This is my "Board" class I have so far, that contains multiple child elements:
Board.h:
#ifndef Board_h
#define Board_h
#include <StandardCplusplus.h>
#include <serstream>
#include <string>
#include <vector>
#include <iterator>
#include "Arduino.h"
#include "Marble.h"
#include "Wall.h"
class Board
{
public:
Board();
void draw(double* matrix);
private:
Marble marble;
//std::vector<Actor> children;
Actor* children[2];
};
#endif
Board.cpp:
#include "Arduino.h"
#include "Board.h"
#include <math.h>
#include <iterator>
#include <vector>
Board::Board()
{
}
void Board::create(double* _matrix, int _cols, int _rows) {
Marble *marble = new Marble();
Wall wall;
children[0] = marble;
//children.push_back(marble);
//children.push_back(wall);
}
void Board::draw(double* matrix) {
Serial.println("board draw");
children[0]->speak();
}
In my "loop" function I am calling
board.draw(matrix);
which results in some nutty Serial code being written out.
Clearly I am not understanding the ins and outs of pointers in arrays in classes here.

You need to make Actor::speak virtual, the compiler uses dynamic binding for virtual methods.
class Actor
{
public:
Actor();
virtual void speak(); // virtual
private:
};

Related

How to override Function in C++

Currently, I am working on c++ project I want to know how I can send an instance of a child class to function use parent as a parameter and execute a function in a child here is an example: I want Child print function to be called
Parent.h
#ifndef UNTITLED_PARENT_H
#define UNTITLED_PARENT_H
class Parent {
public:
virtual void printData();
};
#endif
Parent.cpp
#include "Parent.h"
#include <iostream>
using namespace std;
void Parent::printData() {
cout<<"Parent"<<endl;
}
Child.h
#ifndef UNTITLED_CHILD_H
#define UNTITLED_CHILD_H
#include "Parent.h"
class Child : public Parent{
public:
void printData();
};
#endif
Child.cpp
#include "Child.h"
#include <iostream>
using namespace std;
void Child::printData() {
cout<<"Child"<<endl;
}
ParentUser.h
#ifndef UNTITLED_PARENTUSER_H
#define UNTITLED_PARENTUSER_H
#include "Parent.h"
class ParentUser {
public:
void printer(Parent p);
};
#endif
ParentUser.cpp
#include "ParentUser.h"
void ParentUser::printer(Parent p) {
p.printData();
}
main.cpp
#include <iostream>
#include "Parent.h"
#include "Child.h"
#include "ParentUser.h"
int main() {
Child child;
ParentUser parentUser;
parentUser.printer(child);
return 0;
}
Your function void printer(Parent p); will create a new object of type Parent using a copy constructor your compiler automagically creates for you. You need to change it to take a reference instead:
void printer(Parent& p);
This will make sure that p is actually a reference to child, not a new Parent created from child using a copy constructor.
What's happening here is also called object slicing, as the copy is a parent type, which does not have any of the members defined in the child class.

Casting to a vector of pointers

I have a vector of shared pointers of a pure virtual class IObserver (observers), the vector is a class which inherits IObserver. There is also a second class which inherits IObserver, HomeOwner. I want to cast Homeowner objects to the observers vector, so I can send them to the functions in SecurityStatus but not sure how I go about it. I'd like to do it behind the scenes rather than in the main program. The declaration for both is below.
Thanks!
#pragma once
#include "IObserver.h"
#include "HouseSecurity.h"
#include "SensorInfo.h"
#include <vector>
#include <numeric>
#include <algorithm>
#include <string>
#include <iostream>
using namespace std;
// concrete observer
class HomeOwner : public IObserver{
SensorInfo currentSensorState;
string myName;
string myPhoneNumber;
string myEmail;
HouseSecurity &house;
public:
void Update();
void New();
HomeOwner(string, string, string);
};
#pragma once
#include "IObserver.h"
#include "HomeOwner.h"
#include <vector>
#include <numeric>
#include <algorithm>
#include <string>
#include <memory>
using namespace std;
// subject
class SecurityStatus{
vector <shared_ptr<IObserver>> observers;
public:
void AttachObserver(shared_ptr<IObserver>);
void DetachObserver(shared_ptr<IObserver>);
void NotifyObservers();
};

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();
}

Vector inside a class. C2065 error

I have vector of my own objects inside a class. But when i want to do something with this vector, i have error :/
game.h
#include "renderSystem.h" //there only #include "console_color.h"
#include "level.h" //there only #include "renderSystem.h"
#include "gameObject.h"
class Game {
vector<GameObject> objects;
//something
public:
Game();
//something
};
game.cpp
void Game::initialize() {
GameObject playerObject(GameObjectType_Player);
objects.insert(objects.end(), playerObject);
//something
}
gameObject.h
#include "renderSystem.h"
#include "level.h"
class GameObject {
//something
public:
GameObject(GameObjectType _type);
GameObject() : GameObject(GameObjectType_None) {};
//something
};
And errors are (i cant give you logs, because they are on russian :/ )
C2065 at game.cpp "objects.insert"
C2143 at game.h "vector<GameObject> objects"
C2228 at game.cpp "objects.insert"
C2238 at game.h "vector<GameObject> objects"
C4430 at game.h "vector<GameObject> objects"
I checked #includes, but may be i'm stupid :/
And in every file i have #pragma once
In renderSystem and level i wrote only includes
Wtf?!
Visual studio 2015
//And i have 0:43 AM, so may be i just need to sleep :/
You have two issues here, one, you're not including the vector header file. The second is that the vector class is in the std:: namespace in C++. Here are two possible fixes to this.
#include <vector> /* STL vector */
#include "renderSystem.h" //there only #include "console_color.h"
#include "level.h" //there only #include "renderSystem.h"
#include "gameObject.h"
class Game {
private:
std::vector<GameObject> objects;
public:
Game();
};
Or
#include <vector> /* STL vector */
#include "renderSystem.h" //there only #include "console_color.h"
#include "level.h" //there only #include "renderSystem.h"
#include "gameObject.h"
using namespace std;
class Game {
vector<GameObject> objects;
//something
public:
Game();
//something
};

Undeclared Identifier vector of pointers to objects

Error: Line 12 of Cell.h: 'Actor' undeclared identifier.
If I try to forward declare above it, it says that there's a redefinition. What do I do?
Actor.h:
#ifndef ACTOR_H
#define ACTOR_H
#include <iostream>
#include <vector>
#include <string>
#include "Cell.h"
using namespace std;
class Actor //Simple class as a test dummy.
{
public:
Actor();
~Actor();
};
#endif
Cell.h:
#include <iostream>
#include <string>
#include <vector>
#include "Actor.h"
#ifndef CELL_H
#define CELL_H
using namespace std;
class Cell // Object to hold Actors.
{
private:
vector <Actor*> test;
public:
Cell();
~Cell();
vector <Actor*> getTest();
void setTest(Actor*);
};
#endif
Cell.cpp:
#include "Cell.h"
#include <vector>
vector<Actor*> Cell::getTest() //These functions also at one point stated that
{ // they were incompatible with the prototype, even
} // when they matched perfectly.
void Cell::setTest(Actor*)
{
}
What else can I do?
Remove the #include "Cell.h" from Actor.h and you're set to go.
In general, prefer forward declarations where you can, and includes where you must. I'd also replace the #include "Actor.h" from Cell.h with a forward declaration: class Actor;.
In the cpp files you can include the headers if you need them.
You have recursive #includes via your mutual references between cell.h and actor.h.
In Cell.h, delete #include <Actor.h>.
In Cell.h, add the line class Actor; just above the definition of class Cell.
In Cell.cpp, you might need to add #include "Actor.h".