So, I've got this situation:
#include "ActionLog.h"
class Library{
ActionLog aLog;
// ... the rest of it is private, mind you :D
public:
Library(...);
void addBook(...);
void removeBook(...);
// ... aaand there's a whole bunch of these :)
};
Now, class ActionLog has a public method void log(...);. It should, once implemented, record the beginning of any activity listed as a method of class Library (and eventually it's success/failure, which is optional).
I'm wondering this: Is there some more elegant way of making every class Library's method call the aLog.log(...); method when/before it starts executing? By "elegant" I mean other than just calling it explicitly in every single method...
I am aware of the Python version of the solution for the similar problem, but I'm not familiar with Python, so I'm not even sure that the same class-related principles apply.
C++ doesn't have any means of reflection built-in. There's no way to list methods neither in runtime, nor in compile-time. The best you can do is to hide logging into some #define that you will use to define every method, but preprocessor usage is an antipattern in modern C++.
Stick to the current approach.
As polkovnikov.ph said, without reflection you wouldn't be able to use the python's approach to this.
Just for fun I am going to leave this here but I wouldn't recommend its use:
#include <iostream>
class Logger
{
public:
void log(std::string entry)
{
std::cout << entry << std::endl;
}
};
class A
{
Logger mylog;
public:
void foo()
{
std::cout << "Doing foo" << std::endl;
}
Logger& getLogger()
{
return mylog;
}
};
#define CALL_FUNC_AND_LOG(obj,func) \
{ obj.getLogger().log("Logging "#func); obj.func(); }
int main()
{
A a;
CALL_FUNC_AND_LOG(a,foo);
return 0;
}
http://ideone.com/q0VHj6
Or another version that automatically logs the end of scope of the method.
#include <iostream>
class Logger
{
std::string _entry;
public:
Logger(std::string entry)
{
_entry = entry;
std::cout << "Starting execution of " << entry << std::endl;
}
~Logger()
{
std::cout << "Ending execution of " << _entry << std::endl;
}
};
class A
{
public:
void foo()
{
std::cout << "Doing foo" << std::endl;
}
};
#define CALL_FUNC_AND_LOG(obj,func) \
{ \
Logger _mylogger(""#func); \
obj.func(); \
\
}
int main()
{
A a;
CALL_FUNC_AND_LOG(a,foo);
return 0;
}
http://ideone.com/DHf3xu
Related
I have some types defined by the values of an enumerator, which represent the type of data read in from a file. I wish to do a different processing workflow based on the type of data , but it results in a lot of code duplication:
#include <iostream>
enum dataType {
type1,
type2,
type3
};
struct File {
File(dataType type):type{type}{};
dataType type;
};
void process_file(File file)
{
if(file.type == dataType::type1){ std::cout << "Do work A" << std::endl; };
if(file.type == dataType::type2){ std::cout << "Do work B" << std::endl; };
if(file.type == dataType::type3){ std::cout << "Do work C" << std::endl; };
}
int main(){
File file(dataType::type2);
process_file(file);
return 0;
}
My main problem is with having to check the value via "if" or a switch statement. Imagine there being 50 types instead of just 3 and it becomes quite a chore and error prone to check every single one.
Does anyone know of a way to deal with this? Template code is the obvious thing to try but I'm stuck using the enumerator to determine the type, so I didn't think template code was possible here, at least the attempts I've made have not been successful.
A typical way to get rid of switch is inheritance and virtual function:
struct File {
virtual ~File() = default;
virtual void process() = 0;
};
struct Type1File : public File {
void process() override { std::cout << "Do work A" << std::endl; };
};
struct Type2File : public File {
void process() override { std::cout << "Do work B" << std::endl; };
};
int main(){
std::unique_ptr<File> file = std::make_unique<Type1File>();
file->process();
return 0;
}
How about injecting a SomeWorker object into the file class instead of having a type data member?
class SomeWorker
{
...
public:
virtual void DoWork() = 0;
};
class SomeWorker1 : public SomeWorker
{
...
public:
void DoWork() override { std::cout << "Do work A" << std::endl;}
};
class SomeWorker2 : public SomeWorker
{
...
public:
void DoWork() override { std::cout << "Do work B" << std::endl;}
};
...
struct File {
File(SomeWorker worker):someWorker{worker}{};
SomeWorker someWorker;
};
int main(){
SomeWorker2 someWorker;
File file(someWorker);
file.someWorker.DoWork();
return 0;
}
Obviously, the code is not complete and there are virtual destructors to add and things to improve, but you get the idea...
You can do it passing the dataType as a template parameter.
#include <iostream>
enum class dataType {
type1,
type2,
type3
};
template <dataType T>
struct File {};
void process_file(File<dataType::type1> file) {
std::cout << "Do work A" << std::endl;
}
void process_file(File<dataType::type2> file) {
std::cout << "Do work B" << std::endl;
}
void process_file(File<dataType::type3> file) {
std::cout << "Do work C" << std::endl;
}
int main() {
File<dataType::type1> file1;
File<dataType::type2> file2;
File<dataType::type3> file3;
process_file(file1);
process_file(file2);
process_file(file3);
return 0;
}
However you then also need to accommodate the fact that File is a template, so passing it to other functions ect. is not as easy anymore. You can either change all functions dealing with File to a template aswell, or give all the File variations a common base class.
The other answers seem easier and more to the point in this case to me. Mostly posted this since you mentioned it in your question.
Within JavaScript, you can pull off something like this:
function bunny() { alert("The bunny jumped."); }
var oldBunny = bunny;
function bunny() {
oldBunny();
alert("The bunny also ran.");
}
bunny(); // The bunny Jumped. The bunny also ran.
As one can see, the old "bunny" function had code appended to it by copying to a variable, then recreating the function with the same name. The copy of the original function runs, and the new code also runs.
I wish to replicate a similar mechanic in C++.
Now before you have a meltdown and start explaining the differences between static and dynamic languages, I get it. I'm not looking for something identical to what's provided, but I do desire something similar.
Furthermore, I'm not trying to do this to modify existing code; I wish to format my own source code to allow such a mechanic for other users to take advantage of.
One of the first ideas I had was to perhaps setup various macros within the code that could later be modified by other files.
Another idea would be to create a Signal and Slots system like in QT. Though I have no clue how to do such a thing myself.
Thank you for reading; I hope you have some suggestions.
Well, if you recognize which feature of JavaScript functions makes this possible, it's not too hard to do the same in C++. In JavaScript functions also have closures, which regular function in C++ don't have. But C++ lambdas are of a closure type. And if one defines bunny to be something which can both hold an object of a closure type, and be reassigned, you're all set.
The C++ standard library offers a nice default choice for this, in the form of std::function. We can just re-write your original JavaScript as follows:
std::function<void()> bunny = [] {
std::cout << "The bunny jumped.\n";
};
auto oldBunny = std::move(bunny);
bunny = [oldBunny] {
oldBunny();
std::cout << "The bunny also ran.\n";
};
bunny();
You can use functors.
#include <iostream>
#include <string>
class Base
{
public:
virtual std::string operator ()()
{
return "Base call";
}
virtual ~Base() {}
};
class Derived : public Base
{
public:
virtual std::string operator()()
{
return "Wrapper: " + Base::operator()();
}
};
int main()
{
Base* pFun = new Base;
std::cout << "Now check Base: " << (*pFun)() << std::endl;
delete pFun;
pFun = new Derived;
std::cout << "Now check Derived: " << (*pFun)() << std::endl;
return 0;
}
Assuming the goal is to allow the calling code to extend the program's functionality beyond what the initial code provided, I might use a user-updatable array of functor-objects, something like this:
#include <iostream>
#include <memory>
class Function
{
public:
virtual void Call() = 0;
};
typedef std::shared_ptr<Function> FunctionSharedPointer;
class OldBunny : public Function
{
public:
virtual void Call()
{
std::cout << "The bunny jumped." << std::endl;
}
};
class NewBunny : public Function
{
public:
NewBunny(FunctionSharedPointer oldFunction) : _oldFunction(oldFunction) {/* empty */}
virtual void Call()
{
_oldFunction->Call();
std::cout << "The bunny also ran." << std::endl;
}
private:
FunctionSharedPointer _oldFunction;
};
enum {
FUNCTION_BUNNY,
// other functions could be declared here later...
NUM_FUNCTIONS
};
// Our table of functions that the user can Call() if he wants to
static FunctionSharedPointer _functionTable[NUM_FUNCTIONS];
// Wrapper function, just to keep users from accessing our table directly,
// in case we ever want to change it to something else
void CallFunction(int whichFunction)
{
_functionTable[whichFunction]->Call();
}
// Another wrapper function
void SetFunction(int whichFunction, FunctionSharedPointer newFunctionDefinition)
{
_functionTable[whichFunction] = newFunctionDefinition;
}
// And another
FunctionSharedPointer GetFunction(int whichFunction)
{
return _functionTable[whichFunction];
}
int main(int argc, char ** argv)
{
// Our default function values get set here
SetFunction(FUNCTION_BUNNY, std::make_shared<OldBunny>());
std::cout << "before:" << std::endl;
CallFunction(FUNCTION_BUNNY);
// Now let's update an entry in our function table to do something different!
FunctionSharedPointer op = GetFunction(FUNCTION_BUNNY);
FunctionSharedPointer np = std::make_shared<NewBunny>(op);
SetFunction(FUNCTION_BUNNY, np);
std::cout << "after:" << std::endl;
CallFunction(FUNCTION_BUNNY);
return 0;
}
void bunny()
{
cout << "The bunny jumped." << endl;
}
void oldBunny()
{
bunny();
}
void newBunny()
{
bunny();
cout << "The bunny also ran." << endl;
}
#define bunny newBunny
int main()
{
bunny();
return 0;
}
If you don't need oldBunny(), just remove it.
I'm writing a class where I would like to have some member methods that have some data associated with them, specifically which mechanical systems of a robot they require use of. I thought I could write them as functors, something like this (this isn't my actual code):
class MyRobot : public Robot {
public:
MyRobot();
void runRobot();
private:
Command do_something_,
do_another_thing_;
}
And then initialize do_something_ with a lambda in the constructor like:
do_something_( [] {
do_first_thing();
do_second_thing();
} );
And then tell do_something_ what requirements it has:
do_something_.requires( system_a );
do_something_.requires( system_b );
And in runRobot() I would tell the robot's scheduler to execute the commands:
void MyRobot::runRobot() {
scheduler.add(do_something_);
scheduler.add(do_another_thing_);
}
But I have come to realize that as the number of commands grows, the less manageable the constructor for MyRobot will become, as every command will have its body defined there. I could make a corresponding private method for each command and initialize them with a function pointer instead of a lambda, but that just seems more convoluted. I could also subclass Command for each specific command and thereby have the body and requirements in a separate file for each one, but that feels like a lot of overhead for a fairly simple task. Is there a good way to do this that I'm not aware of?
You can define the Command class to take a std::function and an initializer list of "requirements" as you have them. Then, instead of using lambdas you can make do_something and do_another_thing their own private member functions so you don't have to define their bodies in the constructor. Finally, in the constructor you can construct the Command instances by binding the private member functions with the this pointer of the current MyRobot instance while also giving them a list of requirements. The Command objects should be able to modify the private state of MyRobot instances. An example is below. Also, see example output.
#include <functional>
#include <iostream>
#include <vector>
enum System { SYS_A, SYS_B, SYS_C };
class Command {
public:
typedef std::function<void()> FuncType;
Command(FuncType func, std::initializer_list<System> requirements)
:func_(func), requirements_(requirements) { }
void operator()() {
std::cout << "Executing Command:" << std::endl;
for ( System s : requirements_ )
std::cout << " REQUIRES " << static_cast<int>(s) << std::endl;
func_();
}
private:
FuncType func_;
std::vector<System> requirements_;
};
class Scheduler {
public:
void add(Command c) {
c();
}
};
class Robot {
public:
Robot()
:do_something_ (std::bind(&Robot::do_something, this), {SYS_A, SYS_B}),
do_another_thing_(std::bind(&Robot::do_another_thing, this), {SYS_A, SYS_C}) { }
void runRobot() {
s_.add(do_something_);
s_.add(do_another_thing_);
}
private:
void do_first_thing() { std::cout << " FIRST THING!" << std::endl; }
void do_second_thing() { std::cout << " SECOND THING!" << std::endl; }
void do_third_thing() { std::cout << " THIRD THING!" << std::endl; }
void do_something() { do_first_thing(); do_second_thing(); }
void do_another_thing() { do_first_thing(); do_third_thing(); }
Command do_something_;
Command do_another_thing_;
Scheduler s_;
};
int main(int, char**) {
Robot().runRobot();
}
I've been looking at a few signal/slot implementations, and with no exception they were pretty complicated, some even relying on MOC and extra code generation, like those of Qt.
I realize there are concerns such as threat safety and whatnot, but for a simple, single threaded scenario, is there something wrong with going for a simple approach, something like:
typedef void (*fPtr)();
class GenericButton
{
public:
GenericButton() : funcitonToCall(nullptr) {}
void setTarget(fPtr target) {
funcitonToCall = target;
}
void pressButton() {
if (funcitonToCall) funcitonToCall();
}
private:
fPtr funcitonToCall;
};
void doSomething(){
std::cout << "doing something..." << std::endl;
}
void doSomethingElse(){
std::cout << "doing something else..." << std::endl;
}
int main(){
GenericButton myButton;
myButton.setTarget(doSomething);
myButton.pressButton();
myButton.setTarget(doSomethingElse);
myButton.pressButton();
}
It is still possible to chain several other methods and pass data in the target void function. So why all the complexity for something as trivial as executing some code when a button gets clicked.
This is a perfectly sensible solution, but don't restrict yourself to just function pointers. Use std::function which allows you to bind things, call member functions on objects, use lambdas and still resort to a function pointer where it makes sense. Example:
#include <iostream>
#include <functional>
using namespace std::placeholders;
class GenericButton
{
public:
typedef std::function<void()> fPtr;
GenericButton() : funcitonToCall(nullptr) {}
void setTarget(fPtr target) {
funcitonToCall = target;
}
void pressButton() {
if (funcitonToCall) funcitonToCall();
}
private:
fPtr funcitonToCall;
};
struct foo {
void doSomething() const {
std::cout << "doing something in a foo..." << std::endl;
}
static void alternative(int i) {
std::cout << "And another, i=" << i << "\n";
}
};
void doSomethingElse() {
std::cout << "doing something else..." << std::endl;
}
int main() {
GenericButton myButton;
foo f;
myButton.setTarget(std::bind(&foo::doSomething, &f));
myButton.pressButton();
myButton.setTarget(doSomethingElse);
myButton.pressButton();
myButton.setTarget(std::bind(foo::alternative, 666));
myButton.pressButton();
myButton.setTarget([](){ std::cout << "Lambda!\n"; });
myButton.pressButton();
}
There's almost always a better solution in C++ than function pointers.
If you don't have std::function/std::bind there's always alternatives in boost that work and you can roll your own std::function alternative without too much work which would be worth doing if you want to make something like this.
Most of the signal/slot mechanisms that are around date from a time when things like boost::bind was not a viable option. Those days are long gone and you can get something standard and more flexible for little more complexity than just a function pointer.
I have the following code:
#include <iostream>
using namespace std;
class A
{
int m_value;
public:
A(int value)
{
m_value = value;
funcA(&A::param);
}
void funcA(void (A::*function)(int))
{
(this->*function)(m_value);
}
void param(int i)
{
cout << "i = " << i << endl;
}
};
int main()
{
A ob(10);
return 0;
}
I have a class in which I call a function that receives another function as parameter. The function call is at line funcA(&A::param). What I want is to be able to pass a function as parameter without being necessary to specify the class scope: funcA(¶m). Also I didn't want to use typedefs that's why I have the code a little 'dirty'.
Is there any possibility to achieve this?
This cannot be done. A function pointer in a class must be identified using the class scope (A::function)
That is kind of ugly.
The first thing you should look at doing is recoding things to use inheritence and dynamic dispatch instead. To do this you change the A class to have a virtual method that funcA calls
class A {
...
void funcA () {
custom_function(m_value);
}
protected:
virtual void custom_function (int)=0;
}
Now for every different custom_function you want to use, you declare a new class derived from A, and implement the function in there. It will automagically get called from funcA:
class A_print : public A {
public:
virtual void custom_function (int param) {
std::cout << "param was " << param << std::endl;
}
}
If that isn't flexible enough for you, the next best C++-ish solution would be to implement a functor (an object that acts as a function, possibly even overriding the ()operator.
I don't understand why you can't just do this:
#include <iostream>
using namespace std;
class A
{
int m_value;
public:
A(int value)
{
param(value);
}
void param(int i)
{
cout << "i = " << i << endl;
}
};
int main()
{
A ob(10);
return 0;
}