I'm coming from c#/Java/TypeScript. So do I initialise objects inside a class. For example for a chess game. Lets say I have class for the spot on the board, the board.
So normally it will be
public class Piece()
{
bool isWhite;
Piece(isWhite){
this.isWhite = true;
}
}
public class Spot(){
Piece piece //Chess Piece
Spot(bool isWhite)
{
this.piece.isWhite = isWhite;
}
}
As mentioned in the comment to your post https://cppreference.com/ is usually the best place to look up documentation.
Now about your question:
#include <iostream>
#include <vector>
class Piece
{
public:
~Piece() = default;
explicit Piece(bool isWhite)
{
this->isWhite = isWhite;
}
bool isWhite;
};
class Board
{
public:
Board() = default;
~Board() = default;
void addPiece(Piece p)
{
pieces.push_back(p);
}
std::vector<Piece> pieces;
};
int main()
{
Board b;
Piece p(true);
b.addPiece(p);
std::cout << "Hello World!\n";
return 0;
}
This is how you would usually define a class that has a member from another class.
You should definitely check out constructors and destructors in c++ as they are very important (https://www.tutorialspoint.com/cplusplus/cpp_constructor_destructor.htm).
And as for vector, this is a generic container from the c++ standard library.
Edit: I did indeed forget to add the default keyword to the constructor and destructor of Board which are unnecessary. The reason I've left them there is to showcase their existence to someone new to the language.
Also the reason I didn't pass the piece be reference is because references and pointers might be a complete chapter for someone new to the language.
Basically, the optimal way to write:
void addPiece(Piece p)
{
pieces.push_back(p);
}
is:
void addPiece(const Piece& p)
{
pieces.push_back(p);
}
Related
So I have the main parent class called item and that class has 2 child classes called book and periodical. The ideas behind what I am trying to do is have a polymorphic array or a polymorphic vector that would be able to do something like this:
Now the example is in C# (but I want to do it in C++)
item [ ] items = new items [100];
items[0] = new book();
items[1] = new periodical();
for (int i = 0; i < items.size; i++ ) {
items[i].read();
}
Like I said, the small example code is in C# but I want to do this in C++ but I am not sure how to go about going it. I wanted to use arrays but I'm my research, I haven't found a clear way of how to accomplish this. I also thought if vectors were possible to use or this but I was not sure about that either.
Here is an example (if you have questions let me know):
#include <iostream>
#include <memory>
#include <vector>
class Item
{
public:
virtual ~Item() = default; // base classes with virtual methods must have a virtual destructor
virtual void read() = 0;
};
class Book final :
public Item
{
public:
void read() override
{
std::cout << "book read\n";
}
};
class Periodical final :
public Item
{
public:
void read() override
{
std::cout << "periodical read\n";
}
};
int main()
{
std::vector<std::unique_ptr<Item>> items;
// use emplace_back for temporaries
items.emplace_back(std::make_unique<Book>());
items.emplace_back(std::make_unique<Periodical>());
// range based for loop over unique_pointers in items
// use const& so item cannot be modified and & to avoid copy of unique_ptr (unique_ptr doesn't have a copy constructor)
for (const auto& item : items)
{
item->read();
}
return 0;
}
I am a c++ beginner and learning about smart pointers and inheritance. I have a base class Shape(abstract) and as derived classes I have Triangle, Isosceles and Equilateral.
My idea is to print appropriate print message for each class according to the type which is pointed the base class, which I have declared in the main() as shown below.
#include <iostream>
#include <memory>
class Shape
{
public:
virtual const void triangle()const = 0;
virtual ~Shape(){ std::cout<<"Shape Deleted\n"; }
};
class Triangle: public Shape
{
public:
virtual const void triangle()const override
{ std::cout<<"I am a triangle\n"; }
virtual ~Triangle(){ std::cout<<"Triangle Deleted\n"; }
};
class Isosceles : public Triangle
{
public:
virtual const void triangle()const override
{ std::cout<<"I am an isosceles triangle\n"; }
virtual ~Isosceles(){ std::cout<<"Isosceles Deleted\n"; }
};
class Equilateral: public Isosceles
{
public:
virtual const void triangle()const override
{ std::cout<<"I am an equilateral triangle\n"; }
virtual ~Equilateral(){ std::cout<<"Equilateral Deleted\n"; }
};
When I use traditional way of creating a pointer object using new key word, the distructors of all classes works perfectly(out put is given below).
The main() was:
int main()
{
Shape *Obj[3];
Obj[0] = new Equilateral();
Obj[1] = new Isosceles();
Obj[2] = new Triangle();
for(auto it: Obj)
it->triangle();
delete Obj[0];
return 0;
}
The output is here
But when I change to std::shared_ptr things are different which I could not understand.
The main() was:
int main()
{
std::shared_ptr<Shape> obj[3];
obj[0] = std::make_shared<Equilateral>();
obj[1] = std::make_shared<Isosceles>();
obj[2] = std::make_shared<Triangle>();
for(auto it: obj)
it->triangle();
return 0;
}
The Output Now:
Can anybody help me figure it out, why this happens?
may thanks in advance.
When you use raw pointers you only destroy the first object:
delete Obj[0];
and make other 2 leak, while when you use std::shared_ptr all 3 objects cleaned properly. This is exact reason why using smart pointers is recommended practice.
Actually your second snippet is correct and the output is exactly as expected.
Your first snippet has a bug: you just delete obj[0];. What about obj[1] and obj[2]? If you delete all members of the array, you'll see that the difference between the outputs of two code samples vanish.
The good thing about smart pointers is that they are supposed to be used in a "fire-and-forget" manor.
Finally, read that book of yours with greater caution: you need to master the order of construction and destruction before starting anything about OOP.
I would like to create a simple framework for throwing and catching events in a game. Events could be things like a Collision which (according to the type) can take several arguments (note that every Event type may take another amount of arguments, not just two as in the example).
I would then like to implement functions/classes/... to deal with a Collision, based on polymorphism. This example should illustrate the problem:
#include <iostream>
#include <vector>
class Entity {};
class Player: public Entity {};
class Bomb: public Entity {
public:
bool exploded;
};
class MineSweeper: public Entity {};
// For now, I only included Collisions, but I eventually want to extend it to
// more types of Events too (base class Event, Collision is derived class)
void onCollision(Player* p, Bomb* b) {
if (! b->exploded) {
std::cout << "BOOM";
b->exploded = true;
}
}
void onCollision(Entity* e, Entity* f) {
std::cout << "Unhandled collision\n";
}
// Possibility for Collision between Minesweeper and Bomb later
class Game {
public:
std::vector<Entity*> board; // some kind of linear board
Game() {
board = {new Player, new Bomb, new MineSweeper};
}
void main_loop() {
onCollision(board[0], board[1]); // player and bomb!
onCollision(board[1], board[2]);
}
};
int main() {
Game g;
g.main_loop();
}
Note that I understand perfectly well why the above code doesn't work as intended, I included this example solely to illustrate my problem better.
The above example uses functions for the events, but I'm perfectly fine with classes or any other solution that is maintainable.
I hope it is clear that I would like C++ to decide which event handler to use based on the types of the arguments (presumably at runtime).
My question: How can I do this in C++? An example would be appreciated.
(not my question: fix my code please)
user2864740 provided enough clues for me to find a solution myself. Multiple dispatch was indeed the missing piece.
The following code works as intended, making use of dynamic_cast to dispatch correctly.
#include <iostream>
#include <vector>
class Entity {
virtual void please_make_this_polymorphic() {}
// although this function does nothing, it is needed to tell C++ that it
// needs to make Entity polymorphic (and thus needs to know about the type
// of derived classes at runtime).
};
class Player: public Entity {};
class Bomb: public Entity {
public:
bool exploded;
};
class MineSweeper: public Entity {};
// For now, I only included Collisions, but I eventually want to extend it to
// more types of Events too (base class Event, Collision is derived class)
void onCollision(Player* p, Bomb* b) {
if (!b->exploded) {
std::cout << "BOOM\n";
b->exploded = true;
}
}
void onCollision(Entity* e, Entity* f) {
std::cout << "Unhandled collision\n";
}
void dispatchCollision(Entity* e, Entity* f) {
Player* p = dynamic_cast<Player*>(e);
Bomb* b = dynamic_cast<Bomb*>(f);
if (p != nullptr && b != nullptr) {
onCollision(p, b); // player and bomb
} else {
onCollision(e, f); // default
}
}
class Game {
public:
std::vector<Entity*> board; // some kind of linear board
Game() {
board = {new Player, new Bomb, new MineSweeper};
}
void main_loop() {
dispatchCollision(board[0], board[1]); // player and bomb
dispatchCollision(board[1], board[2]);
}
};
int main() {
Game g;
g.main_loop();
}
Although it works, I'd like to point out some problems with this code:
Manual editing of dispatchCollision needed when adding new Collisions.
Currently, the dispatcher using a simple kind of rule-based system. (Does it fit rule 1? What about rule 2? ...) When adding loads of different functions it needs to dispatch, that may have an impact on the performance.
A collision between A and B should be the same as a collision between B and A, but that isn't properly handled yet.
Solving these problems is not necessarily in the scope of this question IMHO.
Also, the example given should work just as well for more than 2 arguments. (Multiple dispatch, not just double dispatch.)
You should decide first what event subscription model you need.
It could be signal/slot mechanism and you can find plenty of libraries:
https://code.google.com/p/cpp-events/ , http://sigslot.sourceforge.net/ and the like.
Or it could be bubbling/sinking events like in HTML DOM when event gets propagated on parent/child chain ( from event source element to its containers).
Or even other schema.
It is quite easy to create whatever you need with std::function holders in modern C++.
Maybe a good structure for your case could be something like this:
class Entity{
public:
virtual int getType() = 0;
};
enum EntityTypes {
ACTOR,
BOMB,
MINESWEEPER,
};
class Actor : public Entity{
public:
virtual int getType() {return int(ACTOR);}
void applyDamage() {
std::cout << "OUCH";
}
};
class Bomb : public Entity{
public:
Bomb() : exploded(false) {}
virtual int getType() {return int(BOMB);}
void explode() {
this->exploded = true;
}
bool isExploded() {
return this->exploded;
}
protected:
bool exploded;
};
class MineSweeper : public Entity{
public:
virtual int getType() {return int(MINESWEEPER);}
};
class CollisionSolver {
public:
virtual solve(Entity* entity0, Entity* entity1) = 0;
};
class ActorBombCollisionSolver : public CollisionSolver {
public:
virtual solve(Entity* entity0, Entity* entity1) {
Actor* actor;
Bomb* bomb;
if (entity0->getType() == ACTOR && entity1->getType() == BOMB) {
actor = static_cast<Actor*>(entity0);
bomb = static_cast<Bomb*>(entity1);
}else if (entity1->getType() == ACTOR && entity0->getType() == BOMB) {
actor = static_cast<Actor*>(entity1);
bomb = static_cast<Bomb*>(entity0);
}else {
//throw error;
}
if (!bomb->isExploded()) {
bomb->explode();
actor->applyDamage();
}
}
};
class CollisionDispatcher {
public:
CollisionDispatcher() {
CollisionSolver* actorBombCollisionSolver = new ActorBombCollisionSolver;
this->solvers[ACTOR][BOMB] = actorBombCollisionSolver;
this->solvers[BOMB][ACTOR] = actorBombCollisionSolver;
// this part wouldn't be necessary if you used smart pointers instead of raw... :)
this->solvers[BOMB][MINESWEEPER] = 0;
this->solvers[MINESWEEPER][BOMB] = 0;
this->solvers[ACTOR][MINESWEEPER] = 0;
this->solvers[MINESWEEPER][ACTOR] = 0;
}
void dispatchCollision(Entity* entity0, Entity* entity1) {
CollisionSolver* solver = this->solvers[entity0->getType()][entity1->getType()];
if (!solver) {
return;
}
solver->solve(entity0, entity1);
}
protected:
unordered_map<int, unordered_map<int, CollisionSolver*> > solvers;
};
class Game {
public:
std::vector<Entity*> board; // some kind of linear board
Game() : dispatcher(new CollisionDispatcher)
{
board = {new Player, new Bomb, new MineSweeper};
}
void main_loop() {
dispatcher->dispatchCollision(board[0], board[1]);
dispatcher->dispatchCollision(board[0], board[2]);
dispatcher->dispatchCollision(board[1], board[2]);
}
protected:
CollisionDispatcher* dispatcher;
};
int main() {
Game g;
g.main_loop();
}
This way you can easily add new collision solvers, just define the class, and register t in the CollisionDispatcher constructor.
If you use smart pointers you won't need to set zeroes in the map entries not registered, but if you use raw pointers you have to set them to zero OR use unordered_map::find method instead of just grabbing the solver using operator []
Hope it helps!
I have a large class with many methods. This class has a subclass that manages a different situation.
Just to clear it up with an example the actual situation is the following:
class Logic {
public:
virtual void method()
{
Something::getInstance()->doSomething();
}
};
class ArrayLogic : public Logic {
private:
Something** array;
public:
void method() override
{
for (int i = 0; i < AMOUNT; ++i)
array[i]->doSomething();
}
};
Now this pattern repeats itself in multiple methods and I'd like to have just one implementation without trading for performance (since some of this methods are actually already proven to require efficiency).
I was thinking if it's possible with C++11 to have a template solution approach which is able to manage this situation at compile time without the necessity to duplicate the code.
Mind that the array doesn't make sense to exist for Logic so having a Something*[1] is not a viable option.
An additional problem is that at the moment Something** array is not directly contained in ArrayLogic but resides in another class, so it's more like
class ArrayLogic : public Logic {
private:
Container* container;
public:
void method() override {
for (int i = 0; i < AMOUNT; ++i)
if (container->array[i])
container->array[i]->doSomething();
}
}
While having to check for container->array[i] != nullptr may seems strange the fact is that the position is relevant, so an element removed from the array doesn't cause a shift of the successive element but leaves a hole.
I'd try and create separate classes for single and multiplayer games. Base both of these on a base class LogicBase that has a method(Something*) function that calls doSomething() on its parameter. This is what #Pradhan was referring to.
In your main game, you can use a LogicBase* to refer to either a SinglePlayerLogic or a MultiPlayerLogic object and call the relevant method() using a virtual function call.
I'm passing what is stored in Container to the constructor of MultiPlayerLogic. But it could be in a separate class and accessed that way. Similarly, it may be cleaner to pass a Something to the constructor of SinglePlayerLogic, but I wanted to keep the code structure close to your original, so didn't do this.
It initially looks funny for LogicBase to call to a subclass, then have those subclasses call the protected method(Something*) back in the super class. I've seen it elsewhere as a design pattern, but can't recall it's name.
#include <iostream>
#include <vector>
const int AMOUNT = 5;
struct Something {
void doSomething() { std::cout << "Something::doSomething\n"; }
static Something* getInstance() { static Something s; return &s; }
};
class LogicBase {
public:
virtual void method() = 0;
protected:
void method(Something* s) { s->doSomething(); }
};
class SinglePlayerLogic : public LogicBase {
public:
void method() override
{
std::cout << "SinglePlayer::method\n";
LogicBase::method(Something::getInstance());
}
};
class MultiPlayerLogic : public LogicBase {
public:
MultiPlayerLogic(Something **s) : players(s) {}
void method() override
{
std::cout << "MultiPlayer::method\n";
for (int i = 0; i < AMOUNT; ++i) {
if (players[i] == nullptr) {
continue;
}
std::cout << i << " ";
LogicBase::method(players[i]);
}
}
private:
Something** players;
};
int main() {
LogicBase* lb;
SinglePlayerLogic spl;
lb = &spl;
lb->method();
std::vector<Something*> players{AMOUNT};
MultiPlayerLogic mpl(players.data());
lb = &mpl;
lb->method();
}
I need several C++ classes to have a static method "register", however the implementation of register varies between those classes.
It should be static because my idea is to "register" all those classes with Lua (only once of course).
Obviously I can't declare an interface with a static pure virtual function. What do you guys suggest me to do ? Simplicity is welcome, but I think some kind of template could work.
Example of what I would like to achieve
class registerInterface
{
public:
static virtual void register() = 0; //obviously illegal
};
class someClass: public registerInterface
{
static virtual void register()
{
//I register myself with Lua
}
}
class someOtherClass: public registerInterface
{
static virtual void register()
{
//I register myself with Lua in a different way
}
}
int main()
{
someClass::register();
someOtherClass::register();
return 0;
}
Based on how you've described the problem, it's unclear to me why you even need the 'virtual static method' on the classes. This should be perfectly legal.
class SomeClass {
static void register(void) {
...
}
}
class SomeOtherClass {
static void register(void) {
...
}
}
int main(int argc, char* argv[]) {
SomeClass::register();
SomeOtherClass::register();
return 0;
}
Drop the RegisterInterface, I don't think you need it.
If it helps, you could take Hitesh's answer, and add:
struct luaRegisterManager {
template <typename T>
void registrate() {
T::registrate();
// do something else to record the fact that we've registered -
// perhaps "registrate" should be returning some object to help with that
}
};
Then:
int main() {
luaRegisterManager lrm;
lrm.registrate<someClass>();
lrm.registrate<someOtherClass>();
}
More generally, if you want to introduce any dynamic polymorphism in C++, then you need an object, not just a class. So again, perhaps the various register functions should be returning objects, with some common interface base class registeredClass, or classRegistrationInfo, or something along those lines.
Could provide an example of what you feel it is that you need dynamic polymorphism for? Hitesh's code precisely matches your one example, as far as I can see, so that example must not cover all of your anticipated use cases. If you write the code that would be using it, perhaps it will become clear to you how to implement it, or perhaps someone can advise.
Something else that might help:
#include <iostream>
#include <string>
#include <vector>
struct Registered {
virtual std::string name() = 0;
virtual ~Registered() {}
Registered() {
all.push_back(this);
}
static std::vector<Registered*> all;
};
std::vector<Registered*> Registered::all;
typedef std::vector<Registered*>::iterator Iter;
template <typename T>
struct RegisteredT : Registered {
std::string n;
RegisteredT(const std::string &name) : n(name) { T::registrate(); }
std::string name() { return n; }
// other functions here could be implemented in terms of calls to static
// functions of T.
};
struct someClass {
static Registered *r;
static void registrate() { std::cout << "registering someClass\n"; }
};
Registered *someClass::r = new RegisteredT<someClass>("someClass");
struct someOtherClass {
static Registered *r;
static void registrate() { std::cout << "registering someOtherClass\n"; }
};
Registered *someOtherClass::r = new RegisteredT<someOtherClass>("someOtherClass");
int main() {
for (Iter it = Registered::all.begin(); it < Registered::all.end(); ++it) {
std::cout << (*it)->name() << "\n";
}
}
There are all sorts of problems with this code if you try to split it across multiple compilation units. Furthermore, this kind of thing leads to spurious reports from memory leak detectors unless you also write some code to tear everything down at the end, or use a vector of shared_ptr, Boost pointer vector, etc. But you see the general idea that a class can "register itself", and that you need an object to make virtual calls.
In C++ you usually try to avoid static initialisation, though, in favour of some sort of setup / dependency injection at the start of your program. So normally you would just list all the classes you care about (calling a function on each one) rather than try to do this automatically.
Your intentions are noble, but your solution is inkling towards "overengineering" (unless I am missing an obvious solution).
Here is one possibility: You can use the Virtual Friend function idiom For example,
class RegisterInterface{
friend void register(RegisterInterface* x){x->do_real_register();}
protected:
virtual void do_real_register();
}
class Foo : public RegisterInterface{
protected:
virtual void do_real_register(){}
};
class Bar : public RegisterInterface{
protected:
virtual void do_real_register(){}
};
int main(int argc, char* argv[]) {
BOOST_FOREACH(RegisterInterface* ri, registered_interfaces)
{
register(ri);
}
return 0;
}
I know you've already accepted an answer, but I figured I would write this up anyway. You can have self-registering classes if you use some static initialization and the CRTP:
#include <vector>
#include <iostream>
using namespace std;
class RegisterableRoot // Holds the list of functions to call, doesn't actually need
// need to be a class, could just be a collection of globals
{
public:
typedef void (*registration_func)();
protected:
static std::vector<registration_func> s_registery;
public:
static void do_registration()
{
for(int i = 0; i < s_registery.size(); ++i)
s_registery[i]();
}
static bool add_func(registration_func func) // returns something so we can use it in
// in an initializer
{
s_registery.push_back(func);
return true;
}
};
template<typename RegisterableType> // Doesn't really need to inherit from
class Registerable : public RegisterableRoot // RegisterableRoot
{
protected:
static const bool s_effect;
};
class A : public Registerable<A> // Honestly, neither does A need to inherit from
// Registerable<T>
{
public:
static void Register()
{
cout << "A" << endl;
}
};
class B : public Registerable<B>
{
public:
static void Register()
{
cout << "B" << endl;
}
};
int main()
{
RegisterableRoot::do_registration();
return 0;
}
std::vector<RegisterableRoot::registration_func> RegisterableRoot::s_registery;
template <typename RegisterableType> // This is the "cute" part, we initialize the
// static s_effect so we build the list "magically"
const bool Registerable<RegisterableType>::s_effect = add_func(&RegisterableType::Register);
template class Registerable<A>; // Explicitly instantiate the template
// causes the equivalent of
// s_registery.push_back(&A::Register) to
// be executed
template class Registerable<B>;
This outputs
A
B
although I wouldn't rely on this order if I were you. Note that the template class Registerable<X> need not be in the same translation unit as the call to do_registration, you can put it with the rest of your definition of Foo. If you inherit from Registerable<> and you don't write a static void Register() function for your class you'll get a (admittedly probably cryptic) compiler error much like you might expect if there really was such a thing as "static virtuals". The "magic" merely adds the class specific function to the list to be called, this avoids several of the pitfalls of doing the actual registration in a static initializer. You still have to call do_registration for anything to happen.
How about this way? Define an interface class:
// IFoobar.h
class IFoobar{
public:
virtual void Register(void) = 0;
}
Then define the class that handles the register..
// RegisterFoobar.h
class RegisterFoobar{
public:
// Constructors etc...
IFoobar* fooBar;
static void RegisterFoobar(IFoobar& fubar){
foobar = &fubar;
}
private:
void Raise(void){ foobar->Register(); }
}
Now, then define another class like this
// MyFuBar.h
class MyFuBar : IFoobar{
public:
// Constructors etc...
void Register(void);
private:
RegisterFoobar* _regFoobar;
}
Call the code like this:
//MyFuBar.cpp
MyFuBar::MyFuBar(){
_regFoobar = new Foobar();
_regFoobar->RegisterFoobar(this);
}
void MyFuBar::Register(void){
// Raised here...
}
Maybe I have misunderstood your requirements...