Macros for creating named constructors - c++

I am trying to play with c++ and macros for the first time. SO basically in a lecture I know where a coded value is used to distinguish different modes of an object (game_type in this case), then these objects must be created via constructors with meaningful named constructors. SO I created createSinglePlayerGame() and named constructors. Then I tried to optimize this code using macros. SO In the Game class I define the function- like macro consructor A ## operator which runs parameter replacement on the two identifiers and then concatenates the result ("token pasting).
Can you look at my code and suggest a better way of doing this, also do you see any hygiene problem that my macros may be used incorrectly,
class Game
{
public:
#define CONSTRUCTOR(name, a) static Game create_##name() { return Game(a);}
CONSTRUCTOR(Single, 0)
CONSTRUCTOR(Multiple, 2)
// named constructors
static Game createSinglePlayerGame() { return Game(0); }
static Game createMultiPlayerGame() { return Game(1); }
protected:
Game(int game_type);
};
int main()
{
Game myGame = Game::createSinglePlayerGame();
Game second = Game::create_Single();
}

A more conventional way would be:
enum class GameType {
SinglePlayer,
MultiPlayer,
};
class Game
{
public:
explicit Game(GameType type);
};
int main()
{
Game myGame(GameType::SinglePlayer);
}
This is simpler and will be less surprising for other C++ developers to read. It's also less error-prone: even your example code confuses 1 and 2 for multiplayer mode, and since you use raw integers to store it, there's no complaint from the compiler. Using enum class it will be much harder to make such mistakes.

As an alternative to John Zwincks solution, you can also use inheritance:
class Game {
protected:
Game(int game_type);
};
class SinglePlayerGame: public Game {
public:
SinglePlayerGame(): Game(0) {}
};
class MultiPlayerGame: public Game {
public:
MultiPlayerGame(): Game(1) {}
};
int main() {
SinglePlayerGame myGame;
...
}
Although I would only use this method if there were more differences in the interface between single- and multiplayer games than just the constructor.

If you want an alternative to macros you can also use templates. Templates is something that compiler "understand" and optimize.
Their syntax may be confusing at start but if you play with them you can get used to it...
// Tag types for template dispatching
struct SinglePlayer {};
struct MultiPlayer {};
// Default single player
template <typename G>
class Game {
public:
Game () { /* create default single player game */ }
};
// Specialization for multi player
template <>
class Game <MultiPlayer> {
public:
Game () { /* create multiplayer player game */}
};
int main (void) {
Game g1 = Game<SinglePlayer>();
Game g2 = Game<MultiPlayer>();
}
This approach split the class definition into 2. One for single player and one for multi player. If they share a lot of common staff and you believe that this should not be the case, you may consider to avoid the class template and use std::enable_if<> in the constructor's level.
For example:
#include <type_traits>
// Tag types for template dispatching
struct SinglePlayer{};
struct MultiPlayer{};
struct Game {
public:
template <
typename G,
std::enable_if_t<std::is_same<G, SinglePlayer>::value, int> = 0
>
Game(G) { /* create a single player game */ }
template <
typename G,
std::enable_if_t<std::is_same<G, MultiPlayer>::value, int> = 0
>
Game(G) { /* create a multi player game */ }
};
int main (void) {
Game g1 = Game(SinglePlayer{});
Game g2 = Game(MultiPlayer{});
}
Notice that there is no class template any more, only a SFINAE dispatch for the constructors. The disadvantage is the dummy pass of a SinglePlayer{} or MultiPlayer{} object to the constructor.

Related

How do I create an object with sub functions in C++?

I'm not very good at C++ so prepare for improper use of terms.
Basically I want to gather a bunch of functions inside a sub class of another class, so I would interface with it kinda like this:
mainWindow.add.menubar();
^- this is the part I don't know how to do
My class looks something like this at the moment:
namespace GUI {
class Window {
public:
std::string title = "Empty Title";
int show();
// Using a struct didn't work but it's what I have at the moment.
struct add {
int menubar();
};
};
}
Obviously I could simply use mainWindow.addMenubar() but it would be much nicer to add it to a subclass (sub object? I don't know, I'm more used to Javascript programming).
And yes, I'm basically creating my own GUI framework with insufficient C++ expertise, I know it's a bad idea, but it didn't stop me from modifying the Linux kernel to allow me to install Nethunter on my Samsung S4 and it's not gonna stop me now.
You can inject Window* pointer to the struct Add() constructor, something like:
namespace GUI {
class Window {
public:
std::string title = "Empty Title";
Add add; // <- NOTICE: this is an instance of struct Add
// which holds the pointer to the window you want
// to draw on
public:
Window() : add{this} {}
int show();
// Using a struct didn't work but it's what I have at the moment.
struct Add {
Window* win;
Add(Window* w) : win{w} {}
int menubar() {
// here you can use win to draw the puppy :)
}
};
};
}
and then use it like
Widow w;
w.add.menubar();
Of course, you could do more styling here (for the real world code): separate declaration from definition via .h/.cpp files, hide the data you dont want to expose with private, declare Add as a friend class etc.
For it to work, add must be a variable:
#include <string>
namespace GUI {
class Window {
public:
std::string title = "Empty Title";
int show();
// Using a struct didn't work but it's what I have at the moment.
struct Add {
int menubar();
};
Add add;
};
}

Constructors and Copy Constructors accross Identical derived classes

Is it possible to use a copy constructor to initialize an identical derived class from that derived classes "twin"?
I mean I want to initialise an object of type Computer that is identical to an object I already initialised of type User.
Computer cCarrier = User uCarrier; Kind of thing.
E.g
class Game
{
public:
//No constructor Intentional
protected:
int m_iSize;
string m_strName;
};
class User: public Game
{
public:
User(int _iSize, string str_Name);
~User();
};
class Computer: public Game
public:
Computer(int _iSize, string str_Name);
~Computer();
};
main.cpp
#include "game.h"
using namespace std;
int main()
{
User carrier(5, "Airship Carrier");
//Computer carrier = User::carrier;
};
They are identical derived classes, I have only made them this way as a virtual and visual way to represent the User and AI battleships in the programming code, for the programmer, and for testing a sides ships for collisions against each other and firing shots.
Well either you want 2 different types and then you cannot do that ( cannot create a Cat from a Dog), or you want them to share the same type but to be manipulated thru different typenames then you should just use a typedef:
class Game
{
public:
Game(int _iSize, string str_Name);
private:
int m_iSize;
string m_strName;
};
using User = Game;
using Computer = Game;
Nevertheless, from a design standpoint, this way of doing it seem incorrect as a Computer is not a User (IMHO).
On another hand, you could create a constructor in user and in Computer that builds from a Game; something like:
class Computer {
Computer(const Game &game) : Game(game) { /*...*/ }
/*...*/
};
but remains the fact that building a User from a Computer seems "strange".
The only relationship between your User and Computer types is that they both derive from Game.
As such, there is no way to implement a constructor of either by delegating to the other in the way you want (short of containment, which is creating distinct objects, not using the constructor of one type to initialise an instance of an unrelated type).
User and Computer are different type at all. You can add a template copy constructor for it.
Add getter in the base class:
class Game
{
public:
//No constructor Intentional
int get_iSize() { return m_iSize; }
string get_strName() { return m_strName; }
protected:
int m_iSize;
string m_strName;
};
then
class Computer: public Game
{
public:
template <typename T>
Computer(const T& t) {
m_iSize = t.get_iSize();
m_strName = t.get_strName();
}
// ...
};
And consider to make the constructor explicit to avoid unexpected implicit casting.

Is it possible to add class members to base class A from derived class?

I was just thinking about it and wondering if it's totally possible, just out of curiosity, as it would be very usefull I think. (but most of my ideas are crazy/insane anyway).
So here it goes:
Is it possible to create a class A, and class B, then add a member to class A by using class B?
Let's suppose we are making a game, or some program in which this would be usefull:
class Player
{
public:
float health;
};
Now, you think of a way to allow extensions by using include files or something:
#define INCLUDE_SPEEDO_METER
#ifdef INCLUDE_SPEEDO_METER
class PlayerSpeedo : public Player
{
public:
float absolute_speed;
//Do some Magic here & there
};
#endif
Now let's suppose we want to access the absolute speed of a player from the Player class like Player.absolute_speed.
Is this possible in any way?
No, that's not possible. You can't "inject" members into another class. Frankly, I can't see why you would ever want to. No one else than you would be aware of this "injected" member.
While you can't syntactically do what you are hoping to do, you can achieve something very close by storing a map in the base class.
class Player
{
public:
Player(float health = 0) { data["health"] = health; }
float health() const { return get("health"); }
float get(std::string const& field) const { return data[field]; }
protected:
std::map<std::string, float> data;
};
class PlayerSpeedo : public Player
{
public:
PlayerSpeedo(float absolute_speed) {data["absolute_speed" = absolute_speed; }
float absolute_speed() const { return get("absolute_speed"); }
};
What you're talking about is not possible in a statically typed language, but it would work in a dynamically typed language (like Python).
A way of achieving that in C++ would be to use a Map between string names of properties and some generic wrapper for property values.
Not quite what you're asking for, but would give you somewhat similar capabilities is the recent proposal for a future version of the C++ standard Call syntax: x.f(y) vs. f(x,y)
This would enable you to write a standalone function float absolute_speed(const Player& p) { return 0.0f; } that you could call via Player p; auto speed = p.absolute_speed() without changing the definition of Player. This is a similar idea to extension methods in C#.
Maybe you like the way which is often done to extend a base class by another class with a template like the following. There is no need for runtime polymorphism which is often a criteria for speed while optimizing can go down to the executed functions without stopping at the virtual functions.
As you can see from the example, it looks like injection of methods and attributes. C++11 offer it to use the constructor from the class which you use to extend the given class very simple. OK, this is a stupied example but maybe it give you an idea how the thing works.
#include <iostream>
class Empty
{
public:
void DoSomething() { std::cout << "Nothing" << std::endl;}
};
class Extender
{
private:
int x;
public:
Extender(int _x):x(_x) {}
void DoSomething() { std::cout << "Value " << x << std::endl; }
};
template <typename ExtendWith>
class User: public ExtendWith
{
public:
using ExtendWith::ExtendWith;
void DoIt() { ExtendWith::DoSomething(); }
};
int main()
{
User<Empty> userEmpty;
userEmpty.DoIt();
User<Extender> userExtended(100);
userExtended.DoIt();
}
I don't think the language could allow what you're trying to do without introducing inconsistencies.
I don't think you want to modify the actual type though, since what you describe is essentially converting a super-type instance into a sub-type instance. You could do this by adding a constructor to the sub-type...
class PlayerSpeedo : public Player {
public:
float absolute_speed;
explcit PlayerSpeedo(const Player& p, float absolute_speed=0, ...) : health(p.health) {
// copy Player values
}
Another option might be storing a reference to the original object, and decorating it. This doesn't alter the type though.

C++ templates: Accessing template variables

I am new to C++ world.
I am trying to implement code using templates.
template<class PageType>
class Book
{
//implementation
public:
PageType* FreeQ; //holds the pointers to pages which are yet to be written
PageType* BusyQ; //holds the pointers to pages which are being written
PageType* DoneQ; //holds the pointers to pages which were written
getPagetoWrite(); //Get from FreeQ and put in BusyQ
setPageAsFree(); //Erase data and put in FreeQ
}
//example for PageType implementation
class PlasticType
{
mutex; // must
status; // must
*prev; // must
*next; // must
Write( );
Read();
}
I want to know whether there is any way to inform the compiler that implementation of PageType must contain specific variables which will be used in class Book implementation (in getPagetoWrite and setPageAsFree) without creating the instance of the type PageType.
Hope i made myself clear.
I dont think that it is possible to enforce that PageType contain specific variables, this is done simple at compile time during template instantiation - and you really dont need anything else. You can use C++11 std::is_base_of to enforce with static_assert that your PageType implements some base class to which you could put getPagetoWrite and setPageAsFree, but still you will have to instantiate your templates - which is OK.
#include <type_traits>
class Base {
};
class X : public Base {
};
class Z {
};
template <typename T>
class Foo {
static_assert(std::is_base_of<Base,T>::value,"must be derived from Base");
public:
Foo() {
}
};
int main(int argc, char** argv) {
Foo<Z> foo_z_type; // gives compile error: static assertion failed: must be derived from Base
Foo<X> foo_z_type; // OK
return 0;
}
http://coliru.stacked-crooked.com/a/bf91079681af3b0e
As far as i know, you can just use the variables' or functions' names that should be there in your code. Like this:
void getPagetoWrite()
{
...
//PageType should have a member called pagenum for which operator++ makes sense
BusyQ->pagenum++;
...
}
If then you instantiate your Book template with some class which doesn't have a pagenum member, you will get a compile time error.

Using C++ templates to create a class with custom components

Let me explain what I am asking for by an example. Imagine I have a class for a car.
Now, the car may have a lot of extras:
4 doors instead of only 2
Automatic door locking
4 Wheel drive
I want to create the class with any combination of these options. Any of these options needs some data members. Imagine the class now looks like this:
class Car {
public:
bool FourDoors;
bool AutomaticDoorLocking;
bool FourWheelDrive;
Door doors[4]; //4 only needed if FourDoors=true
DoorLockingElectronic doorElectronic; //Only needed if AutomaticDoorLocking=true
TransmissionsShafts[4]; //4 only needed for FourWheelDrive=true
void lockDoors() {
if (AutomaticDoorLocking) {
doorElectronic.lockDoors();
} else {
// Do manual door locking
}
}
};
So far so good, but now I want to create a lot of cars, so many that memory gets critical. And I do not need most of the extras in most of those cars.
I could create a base class, and derive classes with those options enabled or disabled.
But I would have to create 2^{#extras} classes to create all possible combinations, with a lot of double code.
So I thought maybe templates could be used? (that is the question).
I can imagine having a flag template, and rewrite the lockDoors like this:
template<int flags>
void Car<flags>::lockDoors() {
if (flags | AutomicDoorLockingFlag) {
doorElectronic.lockDoors();
} else {
// Do manual door locking
}
}
Wonderful! But the class Car<0> still takes a lot of unnecessary space. So:
Can I somehow include or exclude class members depending on a template parameter?
Other Ideas how to deal with the situation are also welcome!
You want to use policy classes:
class FourDoorPolicy { Door m_doors[4]; ... };
class TwoDoorPolicy { Door m_doors[2]; ... };
class AutoDoorLockingPolicy { ... };
class ManualDoorLockingPolicy { void lockDoors(); ... };
class FourWheelDrivePolicy { TransmissionShafts m_shafts[4]; ... };
class TwoWheelDrivePolicy { TransmissionShafts m_shafts[2]; ... };
template <class DoorPolicy = TwoDoorPolicy,
class LockingPolicy = ManualDoorLockingPolicy,
class DrivePolicy = TwoWheelDrivePolicy>
class Car : public DoorPolicy, public LockingPolicy, public DrivePolicy
{
...
};
Put all the policy specific stuff (e.g. lockDoors() function) inside the policy classes rather than the Car class. The Car class inherits these, which is a form of composition (i.e. you are building all their functionality into the Car class).
Note that you should give all the policy classes a protected, non-virtual destructor so that they can only be instantiated as part of a derived class.
You then instantiate customised cars in the normal template manner:
Car<FourDoorPolicy, AutoDoorLockingPolicy, TwoWheelDrivePolicy> myCar;
Of course, you can use typedefs to help with this (and template aliases in C++0x will help a lot, too).
See: Policy-based Design
You probably should look into Policy-based design. Basically, it consists as externalizing behaviors in policy classes and instantiating a template car object with the appropriate policies. A policy class is responsible for the encapsulation of a given behavior.
From an implementation point of view : Car becomes a template where each type argument corresponds to a given policy (for example : DoorLockingPolicy). Your car template can then be "configured" depending the types you choose to instantiate it with : ManualDoorLockingPolicy or AutomaticDoorLockingPolicy.
template<class DoorLockingPolicy /*, class DoorsPolicy, ... */>
class Car : DoorLockingPolicy
{
public:
void lockDoors()
{
/* ... */
DoorLockingPolicy::lockDoors();
}
};
struct ManualDoorLockingPolicy
{
void lockDoors() { /* ... */ }
};
struct AutomaticDoorLockingPolicy
{
void lockDoors() { /* ... */ }
};
int main()
{
Car<ManualDoorLockingPolicy> car1;
Car<AutomaticDoorLockingPolicy> car2;
}
From a performance point of view, policy-based design is a great way to achieve "don't pay for what you don't use" :
Calls to the policy classes can be inlined and introduce no additional cost
The Car template can inherit privately from its policies and benefit from the empty base optimization.
Once again, Modern C++ Design (Andrei Alexandrescu) is a great read on this topic.
The problem as I see it is that you're trying to define a single class which is capable of representing all possible version of a "Car", meaning that each instance contains member data capable of representing all possible cars. This problem was solved eons ago by traditional inheritance.
Define the functionality common to all cars in the base class. Then derive specific classes which add functionality (and member variables which increase the memory footprint). You minimize your memory simply by instantiating the proper sub class. Each instance contains only the members important to that specific type of Car.
One possibility would be to introduce a feature class. The feature class would have some kind of a unique identifier (I've used int for the hell of it, but boost::uuids::uuid would be more preferable). It does nothing but define a feature of some sort:
class Feature
{
private:
int m_nUniqueID;
protected:
Feature(int _uniqueID) : m_nUniqueID(_uniqueID) {};
virtual ~Feature(){};
public:
const int& getUniqueID const {return(m_nUniqueID);};
}; // eo class Feature
From this, we can derive more concrete features:
class DoorsFeature : public Feature
{
private:
int m_nDoors;
public:
static const int UniqueId;
DoorsFeature(int numDoors) : Feature(UniqueId), m_nDoors(numDoors){};
virtual ~DoorsFeature(){};
void lockDoors() { /* lock the doors */ };
}; // eo class DoorsFeature
class ABSFeature : public Feature
{
public:
static const int UniqueId;
ABSFeature() : Feature(UniqueId){};
virtual ~ABSFeature(){};
}; // eo class ABSFeature
And onwards for any kind of feature that the car can have. Note I would not class wheels as a feature because, well, all cars have wheels although the number may differ. I am referring to various traits that can differ wildly such as electronic doors, ABS, etceteras. Suddenly, your car becomes a much simpler container:
class Car
{
private:
int m_nWheels;
std::string m_Colour;
std::vector<Feature> m_Features;
protected:
public:
Car();
~Car();
void addFeature(Feature& _feature) {m_Features.push_back(_feature);};
Feature getFeature(int _featureId) const;
void lockDoors()
{
DoorsFeature& doorsFeature(static_cast<DoorsFeature&>(getFeature(DoorsFeature::UniqueId)));
doorsFeature.lockDoors();
} // eo lockDoors
}; // eo class Car
Given this, you can also go a step further and introduced named feature-sets (much like the option packs you get from a dealer/manufacturer) that can be automatically applied to a car, or range of makes, models and series.
Obviously, I've left a lot out. You may want to pass a reference to the car to each feature, or do otherwise.
Try rewriting your code to use vector instead of arrays. You can use just the space you need, and it's easier too.
#include <vector>
#include <memory>
class Car
{
public:
int getDoorCount() { return doors.size(); }
bool isFourWheelDrive() { return transmissionShafts.size() == 4; }
bool areDoorsAutoLocking() { return automaticDoorLocking.get() != NULL; }
void lockDoors() {
if (automaticDoorLocking.get() != NULL) {
automaticDoorLocking->lockDoors();
} else {
// Do manual door locking
}
}
private:
std::vector<Door> doors;
std::vector<TransmissionsShafts> transmissionShafts;
std::auto_ptr<DoorLockingElectronic> automaticDoorLocking;
};
Notice how Car now supports hatchbacks (5 doors).