Create a temporary interface into an object? - c++

I have an object "World obj;" that has a normal interface of methods for it's typical funcitonality, but I want to have an additional interface of methods specifically for initializing that should only be visible when I specifically need them.
An example might be like this:
class World{
public:
void draw();
void update();
void normalStuff();
void addATree(); // this should not be ordinarily available or visible,
void addACar(); // calling this might break the object
void addAClown();// if it's not in a ready state for it
private:
int m_data;
};
Is there a way to relatively hide addATree(); etc in a way that makes sense? Ideally the mechanism for revealing those methods would also put the object into a ready state for them, or at least fault if it's not possible.

Different approaches would be possible:
Don't change the code, just change the spec
No need to change the code. Change the API specification and if the caller throws garbage in he gets garbage out.
Make the functions check if they are allowed
Always safe.
class World{
public:
...
void addAClown() {
if(not allowed)
throw error or crash or output error message or just return;
else {
do the work;
}
}
private:
int m_data;
};
Write a function that only exposes the Interface if allowed
You can't protect against someone getting the interface early and use it longer than allowed.
You could extract the interface functions into a separate class.
class WorldInterfaceToProtect {
public:
void addATree() = 0; // this should not be ordinarily available or visible,
void addACar() = 0; // calling this might break the object
void addAClown() = 0;// if it's not in a ready state for it
};
then the main class can protect these functions.
class World : protected WorldInterfaceToProtect {
public:
void draw();
void update();
void normalStuff();
protected:
void addATree(); // this should not be ordinarily available or visible,
void addACar(); // calling this might break the object
void addAClown();// if it's not in a ready state for it
private:
int m_data;
};
You then need to add a function that exposes the interface.
class World ... {
public:
WorldInterfaceToProtect *GetInterface() { return allowed_cond ? this : nullptr; }
...
}
Separate the class itself and the builder
This only helps if the functions to be called are only allowed during construction and not later. Depending on the design of the builder you can get a good protection.
class World{
friend class WorldBuilder;
public:
void draw();
void update();
void normalStuff();
protected:
void addATree(); // this should not be ordinarily available or visible,
void addACar(); // calling this might break the object
void addAClown();// if it's not in a ready state for it
private:
int m_data;
};
class WorldBuilder {
static World *Build(...);
}

Perhaps split the world into more composable parts:
struct WorldInterface
{
virtual void draw() = 0;
virtual void update() = 0;
virtual void normalStuff() = 0;
};
class World : public WorldInterface
{
public:
void draw() override { /* actual drawing here */};
void update() override {};
void normalStuff() override {};
private:
int m_data;
};
class TreeWorld : public WorldInterface
{
public:
// takes a reference to the actual world engine and defers work to
// that
TreeWorld(World& worldEngine) : worldEngine_(worldEngine) {}
void draw() override { worldEngine_.get().draw(); };
void update() override { worldEngine_.get().update(); };
void normalStuff() override { worldEngine_.get().normalStuff(); };
void addATree() {
//do tree/world interaction here
}
private:
std::reference_wrapper<World> worldEngine_;
};
class CarWorld : public WorldInterface
{
public:
// takes a reference to the actual world engine and defers work to
// that
CarWorld(World& worldEngine) : worldEngine_(worldEngine) {}
void draw() override { worldEngine_.get().draw(); };
void update() override { worldEngine_.get().update(); };
void normalStuff() override { worldEngine_.get().normalStuff(); };
void addACar() {
//do car/world interaction here
}
private:
std::reference_wrapper<World> worldEngine_;
};
extern void play_tree_game(TreeWorld world);
extern void play_car_game(CarWorld world);
int main()
{
World worldEngine;
// initialise engine here
// play tree-phase of game
play_tree_game(TreeWorld(worldEngine));
// play car phase of game
play_car_game(CarWorld(worldEngine));
}

Good answers all around, I'll just add this because it was missing(?)
class World{
public:
void draw();
void update();
void normalStuff();
private:
int m_data;
};
class BuildableWorld : public World
{
public:
void addATree();
void addACar();
void addAClown();
};
Use the BuildableWorld at initialization phase and then just give a pointer to the base class type for others to use.
Sure, you need some way to give the "built" data for the base class to access, but that was not the issue here, right?

an alternative approach that has not been mentioned so far, may be to let addX() functions take parameters whose existence implies that World is in a valid state. Say, if you cannot add trees to a world without water, let World return an (optional) water object to pass to addTree ... in other words, you need to properly formalize World invariants:
class World{
public:
void normalStuff();
auto getAvaliableWaterBuckets() -> optional<WaterBuckets>;
auto getAvaliableSoil() -> optional<SoilPack>;
//...
void addATree( WaterBuckets&&, SoilPack&& );
//...
};
// in the meanwhile, in user land:
if( auto water = world->getAvaliableWaterBuckets() )
if( auto soil = world->getAvaliableSoil() )
world->addTree( std::move(*water), std::move(*soil) );
else
world->recycleWater( std::move(*water) );
the benefit of this approach is that the user is not forced to think about world state validity ( an error prone task ), he just thinks about what he needs in order to add a tree ( simpler, hard to use incorrectly ). Moreover, this scales well because addX() functions can share different objects ( addFlowers needs water, ... ) enabling the correct management of a possibly complex internal world state.
Of course, IMHO, if you need to use addX() strictly on world construction only ( and you don't plan to add trees later ), then the factory approach already mentioned in the comments seems the way to go ...

Related

How to create a wrapper or intermediate layer to access a class, without exposing it?

I use a third party engine, that has a class "Sprite". My classes use sprite, and call its methods.
There is a probability that "Sprite" will be replaced in the future by some other game engine. I would like to have a layer between my class, and Sprite, so that it is easy to swap out Sprite in future.
I figure there are at least two ways to do this:
Implement a wrapper class that has a bridge method for every method in sprite, and that my code uses to access the sprite.
For Example:
Wrapper{
private:
Sprite* foo;
public:
void method1(){
foo->method1();
}
int method2(){
return foo->method2();
}
}
The downside with this approach is that there is a lot of work to write a method for each method in Sprite, even though all it is doing is just calling the method and returning whatever result. It is also a lot of maintenance work each time there is a change in sprite.
Alternative 2 : Some kind of magic by overloading the -> operator.
struct LoggingFoo : public Sprite {
void log() const { } //Just a method for logging.Doesn't matter.
Foo const *operator -> () const { log(); return this; }
Foo *operator -> () { log(); return this; }
};
Not very sure of all the things to keep in mind with this option ? For example, what happens to class methods ? Does it make sense to publicly inherit Sprite for this use case ?
Note: In practice, there is no object that is intended to inherit from Sprite in my code.
EDIT:
What would be the most concise way to create the wrapper, yet expose all public member variables and functions? For example, not having to specify each and every variable and function to expose ?
You just need to create a Wrapper class that publicly inherits from Sprite and use it. It automatically fully inherits all the methods and variables of the Sprite class in the Wrapper class with the same level of visibility:
class Sprite
{
public:
void foo(){};
void bar(){};
int mode = 0;
};
class Wrapper : public Sprite
{
};
int main()
{
Wrapper w;
w.foo();
w.mode = 5;
w.bar();
}
If in the future you switch to another library, you will inherit Wrapper from the new class and implement only removed or changed methods:
class NewSprite
{
public:
void foo(){}; // same interface
void new_bar(int mode){};
};
class Wrapper : public NewSprite
{
public:
void bar() // wrap new method
{
new_bar(mode);
}
int mode = 0;
};
But a better approach would be to build a higher-level Wrapper interface so that when you completely change the library API, you don't have to rewrite every method:
class Wrapper
{
public:
void do_operation() // high-level interface
{
s_.foo();
s_.mode = 5;
s_.bar();
}
protected:
Sprite s_;
};
class Wrapper
{
public:
void do_operation() // high-level interface
{
s_.foo();
mode = 5;
s_.new_bar(mode);
}
int mode = 0;
protected:
NewSprite s_;
};
int main()
{
Wrapper w;
w.do_operation();
}
You could also consider a slightly different implementation to your wrapper using private (i.e., is implemented in terms of) inheritance.
This implementation removes the burden of wrapping every function and instead just add a using statement for every function you want to expose.
#include <iostream>
class Sprite
{
public:
Sprite() : d_value(0) {}
void method1() { std::cout << "Sprite::method1()\n"; }
void method2() { std::cout << "Sprite::method2()\n"; }
int d_value;
};
class Wrapper : private Sprite
{
public:
using Sprite::method1;
using Sprite::method2;
using Sprite::d_value;
};
int main()
{
Wrapper w;
w.method1();
w.method2();
w.d_value = 3;
return 0;
}
Live Example

Provide PV function content when constructing object in C++

In Java you can create an object whilst at the same time providing (or overloading) abstract functions within the object, thus:
ActionListener al = new ActionListener() {
public void actionPerformed(ActionEvent e) {
// Whatever in here
}
};
I really like that way of doing it, and was wondering if there was some similar construct in C++.
Basically I want a base class with a couple of PV functions declared in it (amongst other stuff), and the user to create an instance of that class whilst at the same time providing the body of the PV functions.
I know I could create child classes, but that seems a little clunky for what I need, where each child class would be unique and only be used to make one instance each.
I have thought about providing lamdas to the constructor and using those instead of actual member functions, but that really seems messy and hard for a novice user to get their head around - not to mention that it would be too rigid (I'd also like to be able to override some non-pure virtual functions optionally).
So is child classes the only way to go, or is there some lesser-known construct in some newer C++ standard that I don't know about that could do what I want?
To expand a little - the idea is to have a class like:
class Thread {
// other stuff
public:
virtual void setup() = 0;
virtual void loop() = 0;
// other functions, some virtual but not pure
};
Thread threadOne {
void setup() {
// Init code for this thread
}
void loop() {
// Run code for this thread
}
};
Thread threadTwo {
void setup() {
// Init code for this thread
}
void loop() {
// Run code for this thread
}
};
Obviously not that syntax, but it gives you an idea of how I'd like to use the class.
It's intended to be run on an embedded system with a slimmed-down C++ implementation (it's g++ but without the full STL). End users aren't the brightest bunch, so it has to be kept as simple to understand as possible.
Anonymous child classes are the closest to what I'd like (though still not perfect). I can use CPP macros to help abstract some of the class implementation syntactic sugar which would help.
Here's a compilable construct I have come up with. Is there anything "wrong" with this approach given the constraints above?
#define THREAD(NAME, CONTENT) class : public Thread {\
public:\
CONTENT\
} NAME;
class Thread {
private:
uint32_t stack[256]; // 1kB stack
volatile bool _running;
public:
virtual void setup() = 0;
virtual void loop() = 0;
void start();
void stop();
uint8_t state();
static void spawn(Thread *thr);
void threadRunner();
};
void Thread::spawn(Thread *thread) {
thread->threadRunner();
}
void Thread::start() {
Thread::spawn(this);
}
void Thread::threadRunner() {
_running = true;
setup();
while (_running) {
loop();
}
}
void Thread::stop() {
_running = false;
}
uint8_t Thread::state() {
return 0;
}
THREAD(myThread,
void setup() override {
}
void loop() override {
}
)
void setup() {
myThread.start();
}
void loop() {
}
Obviously it doesn't actually do anything yet - the whole of the threading back-end is a separate issue, and will be ported over from some existing code I wrote a few years back. I am mainly interested in simplifying the interface for the end user.
There is multiple possibilities, but I'd stick with something simple and versatile: callbacks and lambdas instead of virtual function and inheritance.
class ActionListener
{
std::function<void(int)> _action_performed;
public:
template<class CB>
ActionListener(CB cb) : _action_performed(cb) {}
void click() { _action_performed(0); }
};
int main()
{
ActionListener al([](int n) { std::cout << "Action Performed #" << n << "\n"; });
al.click(); // prints "Action Performed #0"
}
live demo
I'd also like to be able to override some non-pure virtual functions optionally
Which, semantically speaking, means providing a default behavior. This is possible:
ActionListener(CB cb) : _action_performed(cb) {} // construct an AL with the given callback
ActionListener() : _action_performed(default_action_performed) {} // construct an AL with a default callback
void default_action_performed(int n) { /*...*/ }
well, as you already mentioned, one way would be child classes.
another way would be providing some std::functions (or lambdas), either in the constructor or have some set functions.
store the function as a member and call this once your "virtual" member function is called: If you want it optional:
class MyBase
{
public:
MyBase();
void SetFunc(const std::function<int()>& myFun)
{
m_myFun = myFun;
}
int MyVirtFunc()
{
if(m_myFun)
{
return m_myFun();
}
else
{
return 42;
}
}
private:
std::function<int()> m_myFun;
}
if you want the functions given mandatory, put them in the constructor:
class MyBase
{
public:
MyBase(const std::function<int()>& myFun)
: m_myFun(myFun) {}
int MyVirtFun() { return m_myFun(); }
private:
const std::function<int()> m_myFun;
}

C++ passing base type to pure virtual function

i want to understand the behavior of pure virtual functions in derived class when passing to it an argument of same type as (abstract) base class.
to clarify the question, i took the following code from GeeksForGeeks and modified it:
namespace example {
enum Type {ENGINEER, MANAGER};
class Employee
{
private:
const Type worker;
public:
Employee(const Type& worker) : worker(worker) {}
virtual ~Employee {}
virtual void raiseSalary(const Employee&) = 0;
{ /* common raise salary code */ }
virtual void promote(const Employee&) = 0;
{ /* common promote code */ }
};
class Manager: public Employee {
private:
int degree;
public:
//<constructor>\\
virtual void raiseSalary(const Employee&)
{ /* Manager specific raise salary code, may contain
increment of manager specific incentives*/ }
virtual void promote(const Employee&)
{ /* Manager specific promote */ }
};
}
Now, how can we get access to the field degree in derived class Manager inorder to update his degree? since the passed argument to raiseSalary(Employee& employee) could be Manager or Engineer
I think there are two ways to handle that problem. Let's start with some really bad solution: using casting. In that case dynamic_cast. You can try to down cast a type. If dynamic_cast isn't able to do that it is going to return a null pointer or throw an exception (depends on wheather you cast a pointer or a value/reference type). But that approach is going to force you to adapt your casts as more Manager, Engineer types are going to come. You might also need to use friend to allow specific classes to access internals of others. friend is not going to be inherited in the hierarchy, so you are going to end up with many friends => broken, broken, broken :(
An alternative would be to use the Visitor Pattern: http://en.wikipedia.org/wiki/Visitor_pattern
Using the visitor pattern you can also make a base no-op visitor and finer grained Visitors to handle specific stuff. Just a small example (with specific visitors without derivation):
namespace example {
class SalaryRaisingVisitor;
class EmployeePromotingVisitor;
class Employee
{
public:
Employee() {}
//don't forget to implement the copy constructor: read more about rule of 3!!!
virtual ~Employee {}
virtual void accept(SalaryRaisingVisitor const&) = 0;
virtual void accept(EmployeePromotingVisitor const&) = 0;
};
class Manager: public Employee {
private:
int degree;
public:
//<constructorS>
virtual void accept(SalaryRaisingVisitor const& v)
{
v.visit(*this, degree);
}
virtual void accept(EmployeePromotingVisitor const& v)
{
v.visit(*this, degree);
}
};
class Engineer: public Employee {
public:
//<constructorS>
virtual void accept(SalaryRaisingVisitor const& v)
{
v.visit(*this);
}
virtual void accept(EmployeePromotingVisitor const& v)
{
v.visit(*this);
}
};
class SalaryRaisingVisitor
{
void visit(Manager& m, int& degree) //might be const if no internal state changes
{
//...
}
void visit(Engineer& e) //might be const if no internal state changes
{
//...
}
};
}
At the end as you deal with C++, try to avoid virtual functions :) and move everything to static polymorphism :)
You are getting the concept of virtual functions with classes wrong. The class "knows" what it is (via vtable), so you can just write it as class function, not as static global function. Each function inside the class knows all class variables, so you don't have to pass an object of the class.
namespace example {
enum Type {ENGINEER, MANAGER};
class Employee
{
private:
const Type worker;
public:
Employee(const Type& worker) : worker(worker) {}
virtual ~Employee {}
virtual void raiseSalary() = 0;
{ /* common raise salary code */ }
virtual void promote() = 0;
{ /* common promote code */ }
};
class Manager: public Employee {
private:
int degree;
public:
//<constructor>\\
virtual void raiseSalary()
{
//the Employed standard code
Employee::raiseSalary(); //This won't compile since you set the virtual function = 0
//Manager specific raise salary code
degree = 0; //this lazy bastards should do real work like coding stuff
}
virtual void promote()
{
Employee::promote(); //employee common code. This won't compile since you set the virtual function = 0
/* Manager specific promote */
degree = degree * 2;
}
};
Employee array[10];
array[0] = Manager(); //create a manager object on the stack
array[1] = Manager(); //create a manager object on the stack
array[0].raiseSalary(); //Only Mananer0 gets raiseSalary
/*the manager object in array[0] uses its virtual function
to the manager raiseSalary function. The Manager RaiseSalary function
in this case calls the base class raiseSalary function explicitly
via Employee::raiseSalary(); */
You should rather structure your code like this:
class Employee
{
virtual void raiseSalary() = 0;
virtual void promote() = 0;
};
class Manager: public Employee
{
virtual void raiseSalary()
{ /* Manager specific raise salary code, may contain... */ }
virtual void promote()
{ /* Manager specific promote */ }
};
int main()
{
Manager bob;
bob.promote(); // <--- Proper method in the Manager class will be called.
// Current instance will always have the right class.
}
In other words you should seek opportunity to pass the specific derived class as the this parameter. Unfortunately this will not work in complex cases when multiple params are needed. But well, this was the idea of the language designers. The perfect language is not developed yet.
I think that you can't and it's the wanted behaviour.
The only way to do this is to cast you argument (which is quite complicated in C++ since you have four different kind of casting). Other solution is to give to any employee a grade attribute.
Alexis.

Template type restriction based on inheritance

Say I have such classes:
class Scene {
public:
Scene(void);
~Scene(void);
virtual void update(void) = 0;
virtual void construct(void) = 0;
virtual void destroy(void) = 0;
};
class KillTheHedgehogScene : public Scene {
public:
virtual void update(void) override;
virtual void construct(void) override;
virtual void destroy(void) override;
EntitySceneGraph sceneGraph;
};
and I have a SceneManager class that goes something like this:
class SceneManager {
public:
SceneManager(void);
void loadNewScene(Scene* scene);
Scene* getCurrentScene(void);
void update(void);
private:
Scene* _currentScene;
};
The way my code functions now, I would load a new scene by doing the following:
_sceneManager->loadNewScene(new KillTheHedgehogScene());
My issue with this is that whatever scope this is in has made the allocation, and now _sceneManager has to be in charge of it's deallocation. I want the SceneManager to handle both allocation and deallocation. I want to be able to call my loadNewScene() function in this way:
_sceneManager->loadNewScene<KillTheHedgehogScene>();
This way the scene manager can handle both the allocation and deallocation of the object, and gives it all control. My question however is how can I have templates restrict an input type based on inheritance. For example, I wouldn't want to be able to call:
_sceneManager->loadNewScene<SomeRandomOtherClass>();
SomeRandomOtherClass is not a child class of Scene. Is there a way to restrict the type?
To have a better error message when providing invalid template parameter, you may add static_assert, something like:
template <typename T>
void loadNewScene()
{
static_assert(std::is_base_of<Scene, T>::value, "Type should inherit from class Scene");
// Your implementation
}

Visitor pattern and constness

I am running into a problem concerning the visitor pattern and constness.
Assume a visitor pattern implementation in C++ for a small game in which you draw stuff on the screen (depending on the internal state of the drawable objects) and at the same time run a logic that can change their internal state (pretty much any game you can imagine). Please, forgive any errors in code as this is done on the fly.
//Forward declaration of classes and visitor...
//class Game_actor; This one will be abstract, virtual, whatever.
class Game_actor_item;
class Game_actor_player;
class Game_actor_invisible;
class Visitor
{
public:
// virtual void visit(Game_actor& r)=0;
virtual void visit(Game_actor_player& r)=0;
virtual void visit(Game_actor_item& r)=0;
virtual void visit(Game_actor_invisible& r)=0;
};
Then, some interface-like basics:
//This one defines stuff that can be on the screen.
class Drawable
{
public:
virtual void draw(Screen&)=0;
};
//This one defines stuff that changes its state. Let's assume that do_logic
//returns an integer that means something to the controller and can be
//interpreted via a long list of "message_codes" (1=Add score, 2=Substract
//score, 3=Something else...). Each actor will run its logic and return its
//message, that will be stored and interpreted later. This is mostly crap,
//I know, but makes for a quick example.
class Game_actor
{
private:
float x;
float y;
public:
virtual int do_logic()=0;
void accept_visitor(Visitor& v)=0;
};
Next, our object hierarchy: Items and the player are derived from the actor, that defines part of their internal state. They can, of course, be drawn to the screen. There's a particular actor that won't be drawn, because it is invisible and controls something else.
class Game_actor_item: public Drawable, public Game_actor
{
//Lines and lines of code.
virtual void draw(Screen& s) {/* [...] */}
virtual int do_logic() {/* [...] */}
};
class Game_actor_player: public Drawable, public Game_actor
{
//Lines and lines of code.
virtual void draw(Screen& s) {/* [...] */}
virtual int do_logic() {/* [...] */}
};
class Game_actor_invisible: public Game_actor
{
//Lines and lines of code.
virtual int do_logic() {/* [...] */}
};
Finally, visitor specialization. We're gonna define two visitors, one is going to collect all drawable actors and other is going to dispatch messages to the game controller. Drawable actors will be collected from
a vector of its base class
class Visitor_drawing:public Visitor
{
private:
std::vector<Drawable *> draw_all_these;
public:
// virtual void visit(Game_actor& r)
virtual void visit(Game_actor_player& r) {draw_all_these.push_back(&r);}
virtual void visit(Game_actor_item& r) {draw_all_these.push_back(&r);}
//This one won't be drawn.
virtual void visit(Game_actor_invisible&) {}
std::vector<Drawable *> get_me_the_drawables() {return draw_all_these;}
}
class Visitor_logic:public Visitor
{
private:
std::vector<int> messages;
public:
// virtual void visit(Game_actor& r)
virtual void visit(Game_actor_player& r) {messages.push_back(r.do_logic());}
virtual void visit(Game_actor_item& r) {messages.push_back(r.do_logic());}
virtual void visit(Game_actor_invisible&) {messages.push_back(r.do_logic());}
std::vector<int> fetch_me_the_messages() {return messages;}
}
So, that's our setup. It is missing the "accept_visitor" methods, but I'm sure you get the idea here. Every final branch of the hierarchy just does void accept_visitor(Visitor& v) {v.visit(*this);}.
At any given time in our loop we collect drawable things and run logic:
std::vector<Game_actor*> actors;
while(loop)
{
Visitor_drawing dw;
Visitor_logic dl;
for(Game_actor * g : actors)
{
dw.visit(g);
dl.visit(g);
}
std::vector<Drawable *> draw_these=dw.get_me_the_drawables();
std::vector<int> messages=dl.fetch_me_the_messages();
for(Drawable * d : draw_these) d->draw(screen);
for(int * m : messages) interpret_message(m);
};
And here's my problem: I really want to keep my objects const where they should be. One requisite for this is that drawing them is never going to change their internal state (save a mutable int times_drawn, for example) so they could (and should (??)) be const. Doing their logic may change their state at each given turn (for example, moving them around the screen).
Given this particular setup, how would you manage having a const and non const visitor?. I have tried splitting the base visitor into const and non const base classes so they do
class Const_visitor
{
virtual void visit(const Thing&)=0;
};
class Non_const_visitor
{
virtual void visit(Thing&)=0;
};
class Visitor_drawing:public Const_visitor
{
virtual void visit(const Thing&)=0;
};
class Visitor_logic:public Non_const_visitor
{
virtual void visit(Thing&)=0;
};
But it seems that I would have to implement separate "accept_visitor" methods as the compiler doesn't distinguish between calls:
void accept_visitor_const(Const_visitor& v)=0;
void accept_visitor(Non_const_visitor& v)=0;
This leads to all kinds of duplication in the base visitor classes (basically writing everything twice, const and non const versions) and then separating the calls in the main loop: there's no single accept_visitor anymore and you have to know in advance what kind of visitor are you expecting (the side effect is that it really reads "I will accept this visitor that promises not to change my internals", which is somewhat desirable).
Anyway, Am I missing any other option that does not radically change this setup?. Is this a suitable and desirable option?
As always, many thanks in advance.