I am using a Visitor pattern to traverse and print the children of the tree I am operating on. To get indented printing, I specify the indentation level in a style like:
printCurrent();
indentLevel(); // increases static variable
Visitor::visit(elem); // which then prints the children's node data
unindentLevel(); // decreases static variable
In order to make this nicer, I want to implement a function that takes the Visitor::visit with the argument elem and automatically handles the pre-action (indentLevel()) and post-action (unindentLevel()).
Before implementing that function, I need to define a function pointer that will be used as argument for the function. However, I am failing at specifying the argument to the pointer. As an example, let's look into the PrintVisitor which is derived from the Visitor:
void PrintVisitor::visit(BinaryExpr &elem) {
std::cout << formatOutputStr({elem.getNodeName()});
this->incrementLevel();
Visitor::visit(elem); // <-- this is where I want to create a function pointer to
this->decrementLevel();
}
The idea basically is that the PrintVisitor does everything related to printing and all other logic (e.g., traversal logic) is implemented in the base class Visitor. Hence the PrintVisitor::visit needs to execute its specific action (e.g., printing via formatOutputStr) and then execute the Visitor::visit method:
void PrintVisitor::visit(BinaryExpr &elem) {
std::cout << formatOutputStr({elem.getNodeName()});
void (Visitor::*myPt)(BinaryExpr&) = &Visitor::visit; // declare function pointer
executeIndented(myPt, elem); // pass function pointer myPt
}
// ...
void executeIndented("Function f", "FunctionArgs elem") {
// pre-action
this->incrementLevel();
// main action: call function pointer
(Visitor().*f)(elem); // call function pointer with arg
//post-action
this->decrementLevel();
}
My goal is to somehow achieve that both pre- and post-action always are called in each PrintVisitor::visit method. For that I was thinking it would make sense to encapsulate these pre- and post-actions into another function executeIndented which ensures that.
The syntax of (Visitor().*myPt)(elem); looks a little odd to me, is this really the correct way to call the (base) function Visitor::visit with the argument elem using my function pointer myPt?
// EDIT
Using (Visitor(*this).*myPt)(elem); instead also works. What's the difference between those two ways and is either one of those to be preferred?
// EDIT2
Hope that the description of what I am trying to achieve is more clear now.
As I understand, you should have something like:
struct TraversalVisitor : IVisitor
{
void visit(BinaryExpr &elem) final
{
pre_traversal_action(elem);
visit(elem.lhs);
action(elem);
visit(elem.rhs);
post_traversal_action(elem);
}
virtual void pre_traversal_action(BinaryExpr &elem) { /*Nothing */ }
virtual void action(BinaryExpr &elem) { /*Nothing */ }
virtual void post_traversal_action(BinaryExpr &elem) { /*Nothing */ }
void visit(UnaryExpr &elem) final;
// ...
};
struct PrintVisitor : TraversalVisitor
{
void pre_traversal_action(BinaryExpr &elem) override {
std::cout << formatOutputStr({elem.getNodeName()});
incrementLevel();
}
//void action(BinaryExpr &elem) override { /*Nothing */ }
void post_traversal_action(BinaryExpr &elem) override { decrementLevel(); }
// ...
private:
void formatOutputStr(const std::string&);
void incrementLevel();
void decrementLevel();
// ...
};
Whereas you try to implement something like:
struct Visitor : IVisitor
{
virtual visit(BinaryExpr &elem)
{
visit(elem.lhs);
visit(elem.rhs);
}
// ...
};
struct PrintVisitor : Visitor
{
private:
void formatOutputStr(const std::string&);
void incrementLevel();
void decrementLevel();
void executeIndented(Expr& elem) {
incrementLevel(); // pre-action
// Traversal
Visitor::visit(elem);
decrementLevel(); // post-action
}
void visit(BinaryExpr &elem) override {
std::cout << formatOutputStr({elem.getNodeName()});
executeIndented(elem);
}
// ...
};
Your attempt, IMO, just factorize PrintVisitor, without enforcing some traversal strategy.
Related
Well, all I want to do is a "switch" with a function pointer, but with methods pointers. The switch is that if I call the method Run(), it will either redirect to A::RunOn() or A::RunOff() according to Run ptr is pointing to these member functions.
I know it can be done. I did it in plain c but I have searched and googled to do the same thing in c++ but no luck.
class A
{
typedef (void)(A::*RunPtr)(int);
RunPtr RunMethod;
public:
RunMethod Run;
A()
{
Run = RunOff;
}
void SetOn(bool value)
{
if (value)
Run = RunOn;
else
Run = RunOff;
}
void RunOn(int)
{
// RunOn stuff here
}
void RunOff(int)
{
// RunOff stuff here
}
};
So I can call Run() and there will be a switch between the function calls, which I think is more efficient than just doing:
if (on)
RunOn();
else
RunOff();
Don't know how to do it!
Your member function pointer typedef is wrong (Despite the other issues in the shown code). You need
typedef void(A::*RunPtr)(int);
Or you can provide the alias for the member function pointer of class A with the help of using keyword as follows:
using RunPtr = void(A::*)(int);
RunPtr RunMethod;
Now in the SetOn you can do member pointer assignment as follows
void SetOn(bool value)
{
RunMethod = value ? &A::RunOn : &A::RunOff;
}
Now, in order to call the stored member function pointer, you may/ can provide a Run member function as follows:
void Run(int arg)
{
std::invoke(RunMethod, this, arg);
// do something...
}
The call to member function is a bit tricky.
However, this can be done using more generic std::invoke from <functional> header (Since c++17).
Here is the complete example:
#include <iostream>
#include <functional> // std::invoke
class A
{
using RunPtr = void(A::*)(int);
// or with typedef
// typedef void(A::*RunPtr)(int);
RunPtr RunMethod;
public:
void SetOn(bool value)
{
RunMethod = value ? &A::RunOn : &A::RunOff;
}
void Run(int arg)
{
std::invoke(RunMethod, this, arg);
// do something...
}
void RunOn(int arg) { std::cout << "RunOn: " << arg << "\n"; }
void RunOff(int arg) { std::cout << "RunOff: " << arg << "\n"; }
};
int main()
{
A obj;
obj.SetOn(true);
obj.Run(1); // prints: RunOn: 1
obj.SetOn(false);
obj.Run(0); // prints: RunOff: 0
}
(See a Demo)
Your code works fine once you fix the syntax mistakes in it, namely:
Class needs to be class.
in RunMethod Run;, RunMethod is not a type, it is a member variable. You meant to use RunPtr Run; instead (and get rid of RunMethod), but that won't work so well for you (see further below for why).
in Run = RunOn; and Run = RunOff;, you need to fully qualify the method name, and prefix it with the & operator, eg Run = &A::RunOn;.
Try the following:
class A {
public:
typedef void (A::*RunPtr)(int);
RunPtr Run;
A()
{
Run = &A::RunOff;
}
void SetOn(bool value)
{
if (value)
Run = &A::RunOn;
else
Run = &A::RunOff;
}
void RunOn(int param)
{
//RunOn stuff here
}
void RunOff(int param)
{
//RunOff stuff here
}
};
Note, however, that even though you can use Run as a public method pointer like this, the caller will still need to use operator.* or operator->* to actually call it, and that would not look so nice, eg:
A a;
(a.*a.Run)(...);
Online Demo
If you want to be able to call Run() like a.Run(...) then you have to make Run() be a standard method, and have it use a method pointer internally, eg:
class A {
typedef void (A::*RunPtr)(int);
RunPtr RunMethod;
public:
A()
{
RunMethod = &A::RunOff;
}
void SetOn(bool value)
{
if (value)
RunMethod = &A::RunOn;
else
RunMethod = &A::RunOff;
}
void RunOn(int param)
{
//RunOn stuff here
cout << "RunOn: " << param << endl;
}
void RunOff(int param)
{
//RunOff stuff here
cout << "RunOff: " << param << endl;
}
void Run(int param)
{
(this->*RunMethod)(param);
}
};
A a;
a.Run(...);
Online Demo
I want to have objects with one method which calls a function (but every object should have a different function to call). I will try to show you what I mean by showing an example:
class Human
{
public:
void setMyFunction(void func); // specify which function to call
void callMyFunction(); // Call the specified function
};
void Human::setMyFunction(void func) // ''
{
myFunction = func;
}
void Human::callMyFunction() // ''
{
myFunction();
}
void someRandomFunction() // A random function
{
// Some random code
}
int main()
{
Human Lisa; // Create Object
Lisa.setMyFunction(); // Set the function for that object
Lisa.callMyFunction(); // Call the function specified earlier
}
This code (obviously) doesn't work but I hope you understand what I am trying to accomplish.
MfG, TPRammus
You might use std::function.
#include <functional>
class Human
{
std::function<void()> mFunc;
public:
void setMyFunction(std::function<void()> func) { mFunc = func; }
void callMyFunction() { if (mFunc) mFunc(); }
};
Demo
I would suggest using a simple function pointer. Just do this:
class Human
{
public:
using func_t = void (*)();
void setMyFunction(func_t f) {
func = f;
}
void callMyFunction() {
func();
}
private:
func_t func;
};
The reasons why one might prefer function pointers to std::function are:
Performance. Calling std::function tends to be slower, than calling a function by pointer.
std::function needs truly ugly syntax when one needs to bind it to an overloaded function.
Example:
void foo();
void foo(int x = 0);
void check() {
Human h;
h.setMyFunction(&foo);
}
Will fail to compile.
I am trying to apply the Composite pattern, so I need to create a Leaf class and a Composite class, both inheriting from the same Component class. In order for any of my Components to perform their duty they need to ask help from a single Helper object. We have the following
struct Helper {
void provide_help();
};
struct Component {
Component(Helper* helper)
: m_helper(helper) {
}
virtual void operation() = 0;
// the call_for_help function will be used by subclasses of Component to implement Component::operation()
void call_for_help() {
m_helper->provide_help();
}
private:
Helper* m_helper;
};
And here are two different Leaf subclasses:
struct Leaf1
: Component {
Leaf1(Helper* helper)
: Component(helper) {
}
void operation() override {
call_for_help();
operation1();
}
void operation1();
};
struct Leaf2
: Component {
Leaf2(Helper* helper)
: Component(helper) {
}
void operation() override {
call_for_help();
operation2();
}
void operation2();
};
So far, so good. Now the Composite class is giving me grief. The typical implementation is as follows
struct Composite
: Component {
Composite(Helper* helper)
: Component(helper) {
}
void operation() override {
for (auto el : m_children) el->operation();
}
private:
std::vector<Component*> m_children;
};
which by going through the m_children one by one and calling operation on each essentially calls the helper function multiple times, even though one call is enough for all children. Ideally, if the m_children consisted, say, of a Leaf1 and a Leaf2, I would like somehow the Composite operation to call the helper function only once and then call in succession Leaf1::operation1() and then Leaf2::operation2(). Is there any way to achieve what I need? Alternative designs are welcome. I hope my question makes sense. Thanks in advance!
You want a polymorphic operation but you are adding more responability to the method (calling the helper). It's better to separate these two things.
struct Component {
void call_operation(){
call_for_help();
operation();
}
virtual void operation() = 0;
void call_for_help();
};
Remove the call_for_help() from leaf::operation() (making operation1, operation2 redundant, polymorphism) and the rest should work fine.
You can even hide operation() from your public interface, you'll need friendship with your Composite in that case.
As it could happen at any level, one approach could be to handle this at the level of the helper.
A sketch of the approach would be:
class Helper {
bool composite_help = false;
bool help_provided;
public:
void provide_help() {
if ((composite_help && !help_provided) || !composite_help) {
//TO DO: provide help
help_provided = true;
}
}
void start_composite_help() {
composite_help = true;
help_provided = false;
}
void end_composite_help() {
composite_help = false;
}
};
The principle is that the call for help performed by individual components works as before. But when the composite calls for help, you take preacutions to make sure that the call is performed only once:
void operation() override {
m_helper->start_composite_help();
for (auto el : m_children) el->operation();
m_helper->start_composite_help();
}
As said, this is only a sketch: the code provided as such will not work as soon as you have several levels of composites. So this needs to be improved:
instead of a bool composite_help you'd need a counter, which gets incremented when entering a composite operation and decremented when you exit it. In this case, the counter would go back to 0 (re-enabling help) only when the last level of composte has finished its job.
may be the helper performs different operations to provide help. So you could also imagine to have a "transaction id" that uniquely identifies a group of related operations, and you manage the counter not for the helper overall, in a map of active transactions.
finally, the start/end is not so nice. A RAII helper to the helper could make the whole setup more robust (for example when an exception breaks the normal execution flow.)
I think this problem would be better solved with a combination of Composite and Mediator.
Heads up! I'll show you a different version of the mediator pattern, which is not the same as the canonical version.
It's not of the business of your composite structure to know if a helper was called or not. You'd better do this using some kind of event handler.
Since you have only one helper, you could try like this:
class Helper {
public:
void callHelper() { std::cout << "Helper called" << std::endl; }
};
class Mediator {
private:
std::map<std::string, std::vector<Helper>> subscribers;
int updateLimit = -1;
int currentUpdateCount = 0;
void resetUpdateCount() {
currentUpdateCount = 0;
}
public:
Mediator(){}
void subscribe(std::string evt, Helper helper) {
subscribers[evt].push_back(helper);
}
void update(std::string evt) {
for (auto& h: subscribers[evt]) {
h.callHelper();
}
}
void setUpdateLimit(int i) {
updateLimit = i;
resetUpdateCount();
}
void removeUpdateLimit() {
updateLimit = -1;
resetUpdateCount();
}
int getUpdateLimit() {
return updateLimit;
}
void updateLimited(std::string evt) {
if (updateLimit < 0 || currentUpdateCount < updateLimit) {
update(evt);
currentUpdateCount++;
}
}
};
int main(int argc, const char *argv[])
{
Mediator m;
Helper h1, h2;
m.subscribe("bar", h1);
m.setUpdateLimit(1);
// Will be called only once
m.updateLimited("bar");
m.updateLimited("bar");
m.updateLimited("bar");
m.removeUpdateLimit();
return 0;
}
Using it:
Mediator m;
Helper h1, h2;
m.subscribe("bar", h1);
m.setUpdateLimit(1);
// Will be called only once
m.updateLimited("bar");
m.updateLimited("bar");
m.updateLimited("bar");
m.removeUpdateLimit();
So, here is what you do to integrate this to you composite structure. Remove the helper from you nodes, add the Mediator to the base class:
struct Component {
Component(Mediator& mediator)
: m_helper(mediator) {
}
virtual void operation() = 0;
// the call_for_help function will be used by subclasses of Component to implement Component::operation()
void notify() {
m_mediator->updateFiltered(Component::updateEventName);
}
static std::string updateEventName;
private:
Mediator& m_mediator;
};
std::string Component::updateEventName = "update.composite";
struct Leaf1
: Component {
Leaf1(Helper* helper)
: Component(helper) {
}
void operation() override {
notify();
operation1();
}
void operation1();
};
Using it:
Mediator m;
Helper h;
Composite c(m);
Leaf1 l1(m), l2(m);
c.add(l1);
c.add(l2);
m.subscribe(Component::updateEventName, h);
m.setUpdateLimit(1);
// Will be called only once, even if it has childrens
c.update();
m.removeUpdateLimit();
IMPORTANT: This solution is suboptimal, it has some issues, like you having to pass a mediator instance to every node constructor, but it's just a raw idea for you to work on.
Hope it helps!
I need to pass a pointer to a class so some code I don't control. This code automatically free()s the pointer when it is done, but I need the class later. I hoped I could just make a 'wrapper' class that would keep the class from being deallocated without actually preventing the code from accessing it, but virtual calls don't work.
template <class T>
class PointerWrapper:public T
{
public:
T* p;
PointerWrapper(T *ptr)
{
p=ptr;
}
~PointerWrapper(void)
{
}
T* operator->() const
{
return p;
}
T& operator*() const
{
return *p;
}
};
void codeIDontControl(Example *ex)
{
ex->virtualfunction();
delete ex;
}
void myCode()
{
Example *ex=new Example();
codeIDontControl(ex);
do something with ex //doesn't work because ex has been freed
codeIDontControl(new PointerWrapper<Example>(ex));
do something with ex //ex hasn't been freed, but the changes made to it via
// Example::virtualfunction() in codeIDontControl() aren't there anymore
}
Basically, ex->virtualfunction() calls the virtual function in PointerWrapper itself instead of the virtual function in PointerWrapper->p. It seems that it's ignoring the -> operator?
Now, I don't need to use a PointerWrapper-esque class if there's a different way to do this, but it was all I could think of...
I can't modify Example either, but I can subclass it
You should provide Forwarder class - which redirects virtual calls to stored pointer. Freeing of forwarder class will not cause releasing of pointee. This approach does NOT need to do copy (which can be expensive/may be not implemented/or even not make sense):
struct Forwarder : Example
{
Example *impl;
Forwarder(Example *i) : impl(i) {}
void virtualfunction()
{
impl->virtualfunction();
}
};
Full code:
live demo:
#include <iostream>
#include <ostream>
using namespace std;
struct Example
{
virtual void virtualfunction()=0;
virtual ~Example() {}
};
struct Implmenetation : Example
{
bool alive;
Implmenetation() : alive(true) {}
void virtualfunction()
{
cout << "Implmenetation::virtualfunction alive=" << alive << endl;
}
~Implmenetation()
{
alive=false;
cout << "Implmenetation::~Implmenetation" << endl;
}
};
struct Forwarder : Example
{
Example *impl;
Forwarder(Example *i) : impl(i) {}
void virtualfunction()
{
impl->virtualfunction();
}
};
void codeIDontControl(Example *ex)
{
ex->virtualfunction();
delete ex;
}
void myCode()
{
Implmenetation impl;
codeIDontControl(new Forwarder(&impl));
//do something with ex //doesn't work because ex has been freed
impl.virtualfunction();
}
int main()
{
myCode();
}
Output is:
Implmenetation::virtualfunction alive=1
Implmenetation::virtualfunction alive=1
Implmenetation::~Implmenetation
It's bad design, really. Only the allocator should be allowed to free memory. Functions like this are dangerous, as they leave with with dangling pointers.
This is just off the top of my head, maybe you could try something like this? It's not a safe idea, but if someone implemented it I would be interested to know what happens.
class Foo
{
Foo(Foo* copy) : m_copy(copy) {}
~Foo() { if(m_copy) { *m_copy = *this; } } // Use copy constructor to create copy on destuction.
Foo* m_copy;
}
Foo copy(NULL);
Foo* original = new Foo(©);
MethodThatDeletes(original);
// Original should be destroyed, and made a copy in the process.
original = NULL;
// Copy should be a copy of the original at it's last know state.
copy;
You are providing a Example* to codeIDontControl. The overloaded operator-> on PointerWrapper is an for the PointerWrapper type not the Example* type or even the PointerWrapper* type (i.e. for a value or reference of that type not a pointer to that type).
Since the function you need to call isn't controlled by you, you will need to provide a complete wrapper of the type it expects as a wrapper over the instance you wish to control the lifetime of.
As part of an assignment for a data structures class, I am trying to get this over a decade-old code to actually work. The code is found here: http://www.brpreiss.com/books/opus4/
(And to all of the users here who are horrified at such bad design, take heart - this is a homework assignment where the goal is ostensibly to get someone else's code to work. I am not advocating its use.)
Here, the author defined the class Stack and its associated Iterator:
#ifndef STACK_H
#define STACK_H
#include "linkList.h"
#include "container.h"
class Stack : public virtual Container
{
public:
virtual Object& Top () const = 0;
virtual void Push (Object&) = 0;
virtual Object& Pop () = 0;
};
class StackAsLinkedList : public Stack
{
LinkedList<Object*> list;
class Iter;
public:
StackAsLinkedList () : list() {}
~StackAsLinkedList() { Purge(); }
//
// Push, Pop and Top
//
void Push(Object& object);
Object& Pop() override;
Object& Top() const override;
int CompareTo(Object const& obj) const;
//
// purge elements from, and accept elements onto, the list
//
void Purge();
void Accept (Visitor&) const;
friend class Iter;
};
class StackAsLinkedList::Iter : public Iterator
{
StackAsLinkedList const& stack;
ListElement<Object*> const* position;
public:
Iter (StackAsLinkedList const& _stack) : stack(_stack) { Reset(); }
//
// determine whether iterator is pointing at null
//
bool IsDone() const { return position == 0; }
//
// overloaded dereference and increment operator
//
Object& operator*() const;
void operator++();
void Reset() { position = stack.list.Head(); }
};
#endif
I am not sure what the objective is here, because trying to instantiate a StackAsLinkedList::Iter will predictably give an error because it is private. Furthermore, the author doesn't use the iterator he just implemented for stack in the below example, which instead uses the iterator defined in the parent class of Stack called Container to traverse the stack and print the values:
StackAsLinkedList stack;
Iter& i = stack.NewIterator();
stack.Push(*new Int(1) ); //type "Int" is a Wrapper for primitive "int"
stack.Push(*new Int(2) );
...
while ( ! outIter.IsDone() )
{
cout << *outIter << endl;
++outIter;
}
...
But when he creates stack.NewIterator(), a look at the method call in Container shows:
virtual Iterator& NewIterator () const { return *new NullIterator (); }
So the conditional in the while statement will always fail and thus the body will never execute.
This leads me to believe that I should be implementing another NewIterator method for Stack, but I am not sure what the return value should be ( *new StackAsLinkedList::Iter(_stack) ?).
Any ideas?
Adding the following method in StackAsLinkedList seemed to clear up the problem:
Iterator& StackAsLinkedList::NewIterator() const
{
return *new Iter(*this);
}
Also, the order of assignment in main() was also an issue. This seemed to correct it:
StackAsLinkedList stack;
stack.Push(*new Int(1) ); //type "Int" is a Wrapper for primitive "int"
stack.Push(*new Int(2) );
...
Iter& i = stack.NewIterator();
while ( ! outIter.IsDone() )
{
cout << *outIter << endl;
++outIter;
}
I realize that this solution is not ideal - ideally I should refactor or better yet just start over (or just use STL). But as I said above, the goal was to just get this stuff to compile and work within a limited time-frame. So to echo what others have said: please don't use this code!