Inheritance in Arduino Code - c++

I'm writing some Arduino code and attempting to use inheritance in some classes. I have a class "Actor" (my base class) and a class "Marble" (which inherits from Actor). Here are the header files:
Actor.h:
#ifndef Actor_h
#define Actor_h
#include "Arduino.h"
class Actor
{
public:
Actor();
void speak();
private:
};
#endif
Marble.h:
#ifndef Marble_h
#define Marble_h
#include "Arduino.h"
#include "Actor.h"
class Marble : public Actor {
public:
Marble();
virtual void speak();
private:
};
#endif
Actor.cpp:
#include "Arduino.h"
#include "Actor.h"
Actor::Actor()
{
}
void Actor::speak() {
Serial.println("Actor");
}
Marble.cpp:
#include "Arduino.h"
#include "Marble.h"
void Marble::speak() {
Serial.println("Marble");
}
And finally, in the loop function I do:
void loop() {
Marble marble;
Actor children[2];
children[0] = marble;
children[0].speak();
Which results in "Actor" being printed.
I discovered this nice link which seems similar to my issue, but the resolution does not seem to work for me:
http://arduino.cc/forum/index.php?topic=41884.0
So. It seems like when I create my array of "Actors" and try and stick Marble in there it gets cast to an Actor, or something like that. Problem is, I'll have a few different characters that will all inherit from "Actor" and I'd like an array of them to iterate over and call overridden methods on them.
So, perhaps the problem is how I'm approaching this problem, or maybe there's some syntax errors? I don't know!
Thanks for your help,
Kevin

You need to declare speak as virtual in the Actor class, not just in the Marble class; without that, Actor::speak is a non-virtual function, so you will always be called in preference to the virtual Marble::speak.
For what it's worth, this has nothing to do with the Arduino: it's just a straight C++ issue.

Your problem is that children is an array of type Actor. The line children[0] = marble is taking a Marble object, converting it to an Actor object and copying the results to children[0]. Since the call to children[0].speak() is on an Actor, you get the Actor version.
In order for this to work the way you want, you need to copy a pointer or reference to the object rather than the object itself. That is, you want something like `Actor* children[2]':
Marble marble;
Actor* children[2];
children[0] = &marble;
children[0]->speak();
Of course if children has scope outside of loop, this will fail utterly and you'll need to use new to create your marbles.
Better yet, assuming Arduino has the STL, you should use vector and shared_ptr or something similar.
[Update] As Philip notes, this will also require that the speak method in Actor be declared virtual.

Related

Pointer related UE4 crash. Where are my pointers wrong?

I'm creating a third person laser tag shooter thing for fun and I'm having difficulty creating my weapon hierarchy. My main problem is my editor is crashing from an access error from some errors from pointers in my code and I don't understand pointers enough to be able to figure this out myself.
I'm trying to add a weapon to my default pawn ALTPlayer. I'm doing this by using TSubclassOf to ensure I can only attach children of ALTWeapon to my character
If it helps my explanation, current hierarchy is:
APawn->ALTWeapon->ALaserGun
... and I'm planning on adding a bunch more classes with ALTWeapon as their parent. I'm hoping this will make my code organized and easier to code different functionality for each weapon.
With that in mind, I'll start with my ALTPlayer.h file. Here I declare WeaponClass as my subclass variable
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "LTPlayer.generated.h"
class ALTWeapon;
UCLASS()
class LASERTAG_API ALTPlayer : public ACharacter
{
GENERATED_BODY()
public:
// Sets default values
ALTPlayer();
// Player weapon
UPROPERTY(EditAnywhere)
TSubclassOf<ALTWeapon> WeaponClass;
};
Now I'll move into my ALTPlayer.cpp file. Here I'm trying to create an ALaserGun object that's stored in WeaponClass. (I'm also not sure if this is exactly how I'm supposed to do this)
#include "LTPlayer.h"
#include "LaserGun.h"
// Sets default values
ALTPlayer::ALTPlayer()
{
// Creating Weapon
this->WeaponClass->GetDefaultObject<ALaserGun>();
}
At this point, I expect to see an ALaserGun component in my blueprint child of ALTPlayer. Although, since I have the pointer issue that's crashing my editor, I don't know if that's what this code produces.
If anyone has any insight on how to fix my pointers so that I don't get an access violation, that would be awesome!
You're attempting to dereference WeaponClass when you try to access its default object but it hasn't yet been assigned to anything.
You can initialize it in the constructor initializer list, like so:
ALTPlayer::ALTPlayer()
: WeaponClass(ALTWeapon::StaticClass())
{
}
If this is a class that can be set in a Blueprint default, you can also ensure that it has a value by setting it in PreInitializeComponents:
Declaration:
//~ Begin AActor Interface
virtual void PreInitializeComponents() override;
//~ End AActor Interface
Definition:
void ALTPlayer::PreInitializeComponents()
{
Super::PreInitializeComponents();
// Fallback to default Weapon class if none was specified.
if (WeaponClass == nullptr)
{
UE_LOG(LogGameMode, Warning, TEXT("No WeaponClass was specified in %s (%s)"), *GetName(), *GetClass()->GetName());
WeaponClass = ALTWeapon::StaticClass();
}
}

Using an object outside of its declaration file (C++)

(it is be possible that this question has been asked very often already and i am sorry about this repost, but anything i found just didnt help me, since i am relatively a beginner at c++)
so here is an example to show my problem
i have the class monster
class Monster{
public:
Monster();
void attack();
private:
int _health;
int _damage;
};
and i have the class Level
class Level{
Level();
};
i have created the object "snake" from the class Monster in my "main.cpp"
#include "Monster.h"
int main(){
Monster snake;
}
now what do i do if i want to use "snake" in my "Level" class? if i want to do "snake.attack();" inside of "Level.cpp" for example?
If i declare it again in "Level.cpp" it will be a seperate object with its own attributes wont it?
i have always been making the member functions of my classes static until now, so i could do "Monster::attack();" anywhere in my program but with this tachnique i cant have multiple objects doing different things depending on their attributes (snake1, snake2, bat1, etc...)
thanks for the help in advance!
(and sorry for the possibly reoccuring question)
Presuming those snips are your .h files.
Your level.cpp should something like this:
#include "level.h" // its own header
#include "monster.h" // header with Monster::attack() declaration
Level::DoAttack(Monster& monster) { // using snake as parameter.
health = health - monster.attack(); // monster hits us, subtract health.
}
monster.h would be
class Monster{
public:
Monster();
void attack();
private:
int _health;
int _damage;
};
and monster.cpp
Monster::attack() {
// code to calculate the attack
}
I could not completely understand your questions.But from what I understood.I think you want to access a Monster object instantiated in main() to be used inside level.So,here is what you can do.Add a constructor inside the level class which takes a monster object as an argument.Then instantiate a level object and pass the monster object in it.Like this,
Level l=new Level(snake);
By declaring a class you're not creating any objects. You normally declare a class by including the corresponding header file.
So, in Level.h you'd #include <Monster.h>, then you can reference it inside Level.
But seriously, you can't write much C++ code without understanding the basic things such as declaration vs. definition, header files (.h), classes vs. objects, pointers and references, etc. It would be best to invest in a book or at least to read some tutorials online.

c++ class circular reference?

I am working on a little game engine but I got stuck at something. Explanation : I have two classes, cEntity And ObjectFactory :
cEntity
class cEntity:public cEntityProperty
{
Vector2 position;
Vector2 scale;
public:
cEntity(void);
cEntity(const cEntity&);
~cEntity(void);
public:
void init();
void render();
void update();
void release();
};
ObjectFactory
#include "cEntity.h"
#include <vector>
class ObjectFactory
{
static std::vector<cEntity> *entityList;
static int i, j;
public:
static void addEntity(cEntity entity) {
entityList->push_back(entity);
}
private:
ObjectFactory(void);
~ObjectFactory(void);
};
std::vector<cEntity> *ObjectFactory::entityList = new std::vector<cEntity>();
Now I am adding new cEnity to ObjectFactory in cEntity constructor but facing an error related to circular references: for using ObjectFactor::addEntity() I need to define the ObjectFactory.h in cEntity class but it creates a circular reference.
I think your code might have an underlying architectural issue given how you have described the problem.
Your ObjectFactory should be handling the cEntities, which in turn should be unaware of the "level above". From the description of the problem you are having, it implies that you're not sure what class is in charge of what job.
Your cEntitys should expose an interface (i.e. all the stuff marked "public" in a class) that other bits of code interact with. Your ObjectFactory (which is a bit badly named if doing this job, but whatever) should in turn use that interface. The cEntitys shouldn't care who is using the interface: they have one job to do, and they do it. The ObjectFactory should have one job to do that requires it to keep a list of cEntitys around. You don't edit std::string when you use it elsewhere: why is your class any different?
That being said, there's two parts to resolving circular dependencies (beyond "Don't create code that has circular dependencies in the first place" - see the first part to this answer. That's the best way to avoid this sort of problem in my opinion)
1) Include guards. Do something like this to each header (.h) file:
#ifndef CENTITY_H
#define CENTITY_H
class cEntity:public cEntityProperty
{
Vector2 position;
Vector2 scale;
public:
cEntity(void);
cEntity(const cEntity&);
~cEntity(void);
public:
void init();
void render();
void update();
void release();
};
#endif
What this does:
The first time your file is included, CENTITY_H is not defined. The ifndef macro is thus true, and moves to the next line (defining CENTITY_H), before it moves onto the rest of your header.
The second time (and all future times), CENTITY_H is defined, so the ifndef macro skips straight to the endif, skipping your header. Subsequently, your header code only ever ends up in your compiled program once. If you want more details, try looking up how the Linker process.
2) Forward-declaration of your classes.
If ClassA needs a member of type ClassB, and ClassB needs a member of type ClassA you have a problem: neither class knows how much memory it needs to be allocated because it's dependant on another class containing itself.
The solution is that you have a pointer to the other class. Pointers are a fixed and known size by the compiler, so we don't have a problem. We do, however, need to tell the compiler to not worry too much if it runs into a symbol (class name) that we haven't previously defined yet, so we just add class Whatever; before we start using it.
In your case, change cEntity instances to pointers, and forward-declare the class at the start. You are now able to freely use ObjectFactory in cEntity.
#include "cEntity.h"
#include <vector>
class cEntity; // Compiler knows that we'll totally define this later, if we haven't already
class ObjectFactory
{
static std::vector<cEntity*> *entityList; // vector of pointers
static int i, j;
public:
static void addEntity(cEntity* entity) {
entityList->push_back(entity);
}
// Equally valid would be:
// static void addEntity(cEntity entity) {
// entityList->push_back(&entity);}
// (in both cases, you're pushing an address onto the vector.)
// Function arguments don't matter when the class is trying to work out how big it is in memory
private:
ObjectFactory(void);
~ObjectFactory(void);
};
std::vector<cEntity*> *ObjectFactory::entityList = new std::vector<cEntity*>();

How can two Classes in C++ notice each other? [duplicate]

This question already has answers here:
Resolve build errors due to circular dependency amongst classes
(12 answers)
Cross referencing included headers in c++ program
(5 answers)
Closed 9 years ago.
For example a little Computergame with three Classes Player, Bot and Game
Player has a Method that checks if the Player collide with a bot
// Player.h
#include Game.h
#include Bot.h
class Player {
private:
bool collision(Game g) {
for (Bot bot: g.bots)
...
}
};
The Bot.h (kept simple, of cause it has some other attributes like actual position and so far)
// Bot.h
class Bot {
public:
Bot()
};
The Gameclass handles the Gameloop and the List of Bots
//Game.h
#include Bot.h
#include Player.h
class Game {
public:
Player player:
std::vector<Bot> bots
void loop() { player.collision() }
};
So here we have the problem that Game.h includes Player.h and the other way around.
How can I resolve this?
While the other answers here are certainly technically correct, whenever I come across a situation like this I see it as pointing out a potential flaw in my design. What you have is cyclic dependencies, like so:
This isn't just a problem for your implementation, it means that there is too much coupling between classes, or, conversely, too little information hiding. This means that you can't design the Player independently of the Game, for example.
So if possible, I'd prefer a situation like this, where the Game, as the controller delegates work out to other classes.
One way to do this is for the Game to pass references to its own properties as and when the Player needs them.
For example have collision take a bots parameter rather than the `Game
bool collision(const std::vector<Bot&> bots) {
// note pass objects by const ref is usu preferred in C++ to pass by value
for (Bot bot: g.bots)
...
}
(Note in a more sophisticated approach, it could pass interfaces, i.e. abstract base classes, onto itself).
If all else fails, you can go back to using a forward declaration.
In this case the easiest thing would be a forward declaration, and moving some code from the header file to the source file.
Like this
Player.h
#include "Bot.h"
class Game; // forward declaration
class Player {
private:
bool collision(Game g);
};
Player.cpp
#include "Player.h"
#include "Game.h"
bool Player::collision(Game g) {
for (Bot bot: g.bots)
...
}
The forward declaration tells the compiler that Game is the name of a class but nothing else. So the Player::collision method must be moved to the Player.cpp file where the full definition of Game is available.
I dont think you can do this since If A contains B, and B contains A, it would be infinite size. Infact you can create two classes that store pointers to one another, by using the forward declaration, so that the two classes know of each other's existence
Forward declaration is required - http://en.wikipedia.org/wiki/Forward_declaration

Classes, namespaces and inheritance help for D&D game

So for class we have to make a D&D 3.5 game, and for the first assignment I have to generate a Fighter character. The way I have the hierarchy set up in my head is character.cpp and it's child is classname.cpp where it has some attributes specific to the class since all classes share the same basic things.
Is that a good structure for it? If it's related we haven't done STL yet.
Another issue that arose is since my teammate will be making a GUI for the game he may also make a class called character. I thought to resolve this I would make a namespace. But if I make each of the files I make have their class inside namespace d20 in each of their respective headers would all of those namespaces be one and the same? I can't think of a very good way to word this question.
Here's my best stab at answering you...
A good inheritance structure is very context specific, but the basic principle is a base class contains data and functions relevant to all the derived classes. Derived classes will contain specific data and functions to itself. In your case there will be a lot of data in the base class 'character' like all the character stats and functions that compute outcome based on stats (I'm assuming the rules of the game are generally class independent).
I'm also assuming when you say 'classname.cpp' you mean 'fighter.cpp', 'cleric.cpp', etc. In that case, yes, I would agree with making it structured that way.
STL doesn't really have a direct impact on coming up with class hierarchies, so I would say no, it's not related.
As for namespaces, anytime you specify a namespace it will be the same as anywhere else you specify the exact same name (which is what I think you're asking). You don't need to do anything special to make it the same namespace other than naming it the same exact thing. A simple example is as follows:
character.h
namespace d20
{
class Character
{
Character();
~Character();
//etc...
}
}
character.cpp
#include "character.h"
namespace d20
{
Character::Character()
{
// Stuff...
}
Character::~Character()
{
}
}
fighter.h
#include "character.h"
namespace d20
{
class Fighter : public Character
{
Fighter ();
~Fighter ();
//etc...
}
}
OR (without the namespace keyword)
#include "character.h"
class Fighter : public d20::Character
{
Fighter ();
~Fighter ();
//etc...
}
Edit: Please note that in the second case the Fighter class is NOT is the namespace d20, it just derives from a class in that namespace.
For your case I would recommend against inheritance, because inheritance is usually used two ways: where you always use the base class, and never upcast, or using inheritance. The first is not what you want, and the second can be slightly tricky. (Also makes multiclassing impossible) In the long run, a very generic character class will get you farther.
namespace d20 {
enum classtype {warrior_class, cleric_class, rogue_class, mage_class};
class character {
classtype charclass;
int hp;
int bab;
int str;
string get_name();
void hit(character* enemy);
};
}
On the other hand, if this is simply a homework assignment, and you want to keep things super simple, inheritance with virtual functions might make simple programs easier.
namespace d20 {
class character {
int hp;
int bab;
int str;
virtual string get_name() = 0;
virtual void hit(character* enemy) const;
};
}
namespace d20 {
class fighter {
string get_name() {return "Fighter";}
void hit(character* enemy);
}
}
That sounds like a reasonable approach to me. Presumably classname.cpps would be better named as something like cleric.cpp, barbarian.cpp etc.
You could make your baseclass with a protected function like 'rollstats' to return a string containing stats. Child classes could then override that with a public rollstats function which calls the the base class' method and then append additional stats.
If your classmate is creating the GUI, he should be using your classes shouldn't he? In which case he should just be importing your .h / .cpp files and there's no need to necessarily worry about namespaces.