Why does this simple example not compile, and how can I get around the problem?
#include <iostream>
#include <boost/signals2/signal.hpp>
struct HelloWorld {
HelloWorld() {
i = 0;
}
void operator()() {
std::cout << "I is: " << i++ << std::endl;
}
void setup () {
sig.connect(this);
}
void run () {
sig();
}
boost::signals2::signal<void ()> sig;
private:
int i;
};
int main()
{
HelloWorld hello;
hello.setup();
hello.run();
hello.run();
hello.run();
return 0;
};
You are trying to connect to a pointer, which isn't possible. Instead you need to connect to a reference to your object:
void setup () {
sig.connect(boost::ref(*this));
}
Related
Does this code architecture cause memory leakage by not freeing m_func?
And could this be tempered with if this code would be executed at a closed server? Like finding the address of the pointer and replacing the code of the function pointee with malicious code? If so how could I solve this?
#include <iostream>
template <typename Func>
struct endpoint_t {
void* m_func;
endpoint_t(Func&& func) : m_func((void*) func) {}
auto execute() {
return ((Func*) m_func)();
}
};
int hello_world() {
std::cout << "Hello World! \n";
return 0;
}
int main() {
endpoint_t end(hello_world);
end.execute();
}
Edit:
This is the actual goal of the code: To store multiple endpoint functions inside a vector.
#include <vector>
#include <iostream>
template <typename Func>
struct endpoint_t {
void* m_func;
endpoint_t(Func&& func) : m_func((void*) func) {}
auto execute() {
return ((Func*) m_func)();
}
};
int hello_world() {
std::cout << "Hello World! \n";
return 0;
}
int hello_world2() {
std::cout << "Hello World 2! \n";
return 0;
}
int main() {
std::vector<endpoint_t<???>> array;
array.push_back(hello_world);
array.push_back(hello_world2);
}
Assuming the prototypes of all your 'hello world' functions is the same (int return value, no parameter), you don't need templates at all. Just store a function pointer.
typedef int (*Func_t)();
int hello_world() {
std::cout << "Hello World! \n";
return 0;
}
int hello_world2() {
std::cout << "Hello World 2! \n";
return 0;
}
int main() {
std::vector<Func_t> array;
array.push_back(&hello_world);
array.push_back(&hello_world2);
}
Assuming that the prototypes do differ, it becomes a wee bit more difficult, but not very much so, thanks to std::function.
int hello_world() {
std::cout << "Hello World! \n";
return 0;
}
int hello_world2(int value) {
std::cout << "Hello World 2! \n";
return 0;
}
int main() {
std::vector<std::function<int ()>> array;
array.push_back(&hello_world);
array.push_back(std::bind(&hello_world2, 2));
}
Please note, that std::bind and lambdas require you to pass any given parameter at the time of binding. You cannot add the parameter later.
At first it seemed clear that I shouldn't be able to do this, but then I discovered that it can be done with free functions.
Here is an example where I pass void() functions from Child to Parent. The parent calls the function when their Frame comes up.
I have figured out the syntax to pass free functions with arguments, but I can't figure out how to pass a member function of Child with an argument.
Please help.
#include <iostream>
#include <vector>
#include <map>
#include <functional>
void f_Free1() { std::cout << "Hi there hello. I'm a free function without arguments."; }
void f_Free2(int i) { std::cout << "Hi there hello. I'm a free function with an argument. It's " << i; }
class Parent
{
std::map<unsigned int, std::vector<std::function<void()>>> Tasks;
protected:
void addTask(unsigned int frame, std::function<void()> task) { Tasks[frame].push_back(task); }
public:
virtual ~Parent() {}
unsigned int Frame = 0;
void tick()
{
if (Tasks.count(Frame))
{
for (auto task : Tasks[Frame])
{
task();
}
}
Frame++;
}
};
class Child : public Parent
{
void f_Child1() { std::cout << "This is a private Child function without arguments. "; }
void f_Child2(int i) { std::cout << "This is a private Child function with an argument. It's " << i; }
public:
Child()
{
addTask(3, f_Free1);
addTask(5, [a = int(4)] () { f_Free2(a); } ); // THIS WORKS!!!
addTask(7, std::function<void()> { std::bind(&Child::f_Child1, this) });
addTask(9, std::function<void()> { std::bind([a = int(4)]() { &Child::f_Child2(a), this) } }); // CAN'T MAKE THIS WORK
}
};
int main()
{
Child child;
for (unsigned int i = 0; i < 12; i++)
{
std::cout << "[" << child.Frame << "]";
child.tick(); // runs tasks whose frames are up
std::cout << std::endl;
}
return 0;
}
Ditch the bind.
Use [this]() { f_Child1(); } and [this]() { f_Child(4); }.
Also, the free version can be just []() { f_Free2(4); }.
std::bind's syntax would be:
std::bind(&f_Free1)
std::bind(&f_Free2, 4)
std::bind(&Child::f_Child1, this)
std::bind(&Child::f_Child2, this, 4)
But lambda is simpler for most people:
&f_Free1 is fine, else [](){ return f_Free1(); }
[](){ return f_Free2(4); }
[this]() { return this->f_Child1(); )
[this]() { return this->f_Child2(4); )
return can be omitted here as functions return void.
this-> can be omitted in lambda.
you might capture more or differently for arguments.
The idea is to call different functions based on their index in table.
But line 27 generates the runtime error ((
I tried to fix but didn't succeed (((
Here's the simplified code:
#include <iostream>
void f1 (void) {
std::cout << "f1" << "\n";
}
void f2 (void) {
std::cout << "f2" << "\n";
}
typedef void (*fPtr[3])(void); // simple "[]" instead of "[3]" gets the compile error
class modeChanger {
public:
modeChanger (fPtr funcArray);
void op ();
private:
fPtr *_funcArray;
};
modeChanger::modeChanger (fPtr funcArray) {
_funcArray = (fPtr *) funcArray;
}
void modeChanger::op () {
(*_funcArray[0])();
(*_funcArray[1])(); // Line 27: this line generates a runtime error! Just comment it to get all work
}
void (*modeFuncArray[])(void) = {f1, f2, f2};
modeChanger *mode = new modeChanger (modeFuncArray);
int main() {
(*modeFuncArray[1])(); // Works fine
mode->op(); // generates a runtime error
return 0;
}
This works good:
(*_funcArray[0])();
as well as this:
(*modeFuncArray[1])();
but this generates a runtime error...
(*_funcArray[1])();
Seems that incrementing of _funcArray is incorrect for some reason.
fPtr *_funcArray; this is the pointer to array, not an array of pointers. You suppressed warnings with help of type casts. See bellow the fixed code.
#include <iostream>
void f1 (void) {
std::cout << "f1" << "\n";
}
void f2 (void) {
std::cout << "f2" << "\n";
}
typedef void (*fPtr)(void);
class modeChanger {
public:
modeChanger (fPtr *funcArray);
void op ();
private:
fPtr *_funcArray;
};
modeChanger::modeChanger (fPtr *funcArray) {
_funcArray = funcArray;
}
void modeChanger::op () {
(*_funcArray[0])();
(*_funcArray[1])(); // Line 27: this line generates a runtime error! Just comment it to get all work
}
void (*modeFuncArray[])(void) = {f1, f2, f2};
modeChanger *mode = new modeChanger (modeFuncArray);
int main() {
(*modeFuncArray[1])(); // Works fine
mode->op(); // generates a runtime error
return 0;
}
Applying #Someprogrammerdude's advice:
#include <iostream>
#include <array>
#include <functional>
void f1 (void) {
std::cout << "f1" << "\n";
}
void f2 (void) {
std::cout << "f2" << "\n";
}
using fPtr = std::function<void()>;
using fPtrs = std::array<fPtr, 3>;
class modeChanger {
public:
modeChanger (fPtrs funcArray);
void op ();
private:
fPtrs _funcArray;
};
modeChanger::modeChanger (fPtrs funcArray) : _funcArray(funcArray) { }
void modeChanger::op () {
_funcArray[0]();
_funcArray[1]();
}
int main() {
fPtrs modeFuncArray = {f1, f2, f2};
modeChanger mode(modeFuncArray);
modeFuncArray[1]();
mode.op();
return 0;
}
And thus instead of "hard to declare" C types, we have things as easy as int, and all is well.
as you use c++, you should use c++ features and not C, you should use <functional>
#include <iostream>
#include <functional>
void f1(void) {
std::cout << "f1" << "\n";
}
void f2(void) {
std::cout << "f2" << "\n";
}
typedef void(*fPtr[3])(void); // simple "[]" gets the compile error
class modeChanger {
public:
modeChanger(std::function<void(void)>* funcArray);
void op();
private:
std::function<void(void)> * _funcArray;
};
modeChanger::modeChanger(std::function<void(void)>* funcArray) {
_funcArray = funcArray;
}
void modeChanger::op() {
_funcArray[0]();
_funcArray[1](); // this line generates a runtime error! Just comment it to get all work
}
std::function<void(void)> modeFuncArray[] = { f1, f2, f2 };
modeChanger *mode = new modeChanger(modeFuncArray);
int main() {
modeFuncArray[1](); // Works fine
mode->op(); // generates a runtime error
return 0;
}
For example, I have such function which performs some useful work (for event-driven simulation):
int function()
{
do_useful_work();
return 0;
}
If I need do measurements of performance of this useful_work I should do:
int function()
{
count_time(time_before);
count_X_metrics(X_before);
do_useful_work();
count_time(time_after);
count_X_metrics(X_after);
return 0;
}
This approach makes code more clumsy. Is there a way, patters to do these countings outside of int function() to make code clearer?
You could create your own decorator like the following:
#include<functional>
#include <iostream>
void count_time() {};
void count_X_metrics() {};
void decorator(std::function<void()> work)
{
count_time();
count_X_metrics();
work();
count_time();
count_X_metrics();
}
void do_work_1() {
std::cout << "Hello, World 1!" << std::endl;
}
void do_work_2() {
std::cout << "Hello, World 2!" << std::endl;
}
int main() {
decorator(do_work_1);
decorator(do_work_2);
}
Edit: I'm not sure how your count_time and count_X_metrics functions work, but if you need something more complicated, or a way to keep track of state, you can create an object that will do that work for you. This is certainly different than you need, but hopefully it conveys the point I am trying to make:
#include<functional>
#include <iostream>
int current_time() { return 0; }
int x_metric() { return 0; }
class Timer {
public:
void time(std::function<void()> work) {
// Capture state before
int starttime = current_time();
int startmetric = x_metric();
work();
// Capture state after
int endtime = current_time();
int endmetric = x_metric();
// Update results
ellapsed = endtime - starttime;
metric = endmetric - startmetric;
// Possibly do something with the metrics here.
// ...
}
int get_ellapsed() { return ellapsed; }
int get_metric() { return metric; }
private:
int ellapsed;
int metric;
};
void do_work_1() {
std::cout << "Hello, World 1!" << std::endl;
}
void do_work_2() {
std::cout << "Hello, World 2!" << std::endl;
}
int main() {
Timer t;
t.time(do_work_1);
// Possibly do something with the metrics here.
// cout << t.get_ellapsed();
t.time(do_work_2);
}
I created a class that represents a packet of information as described on this code:
#ifndef PACKET_H_
#define PACKET_H_
namespace std {
class Packet
{
public:
Packet();
virtual ~Packet();
void initClass();
void setStartP(char);
void setAddFrom(char);
void setAddTo(char);
void setpDataSize(char);
void setpNumber(char);
void setChecksum(char);
void setEndP(char);
void LoadData(char);
char getStartP();
char getAddFrom();
char getAddTo();
char getpDataSize();
char getChecksum();
char getEndP();
char getData();
private:
char pB[261];
char pDataMax;
char pDataIndex;
};
} /* namespace std */
#endif /* PACKET_H_ */
#include "Packet.h"
#include <iostream>
namespace std {
Packet::Packet()
{
pDataIndex = 0;
initClass();
}
Packet::~Packet()
{
delete this;
}
void Packet::setStartP(char startChar)
{
pB[0] = startChar;
cout << "in Set!";
}
void Packet::setAddFrom(char fromChar)
{
}
void Packet::setAddTo(char toChar)
{
}
void Packet::setpDataSize(char dataSizeChar)
{
}
void Packet::setpNumber(char packetNumber)
{
}
void Packet::setChecksum(char checksumChar)
{
}
void Packet::setEndP(char endChar)
{
}
void Packet::LoadData(char dataChar)
{
}
char Packet::getStartP()
{
return pB[0];
cout << "in Get";
}
char Packet::getAddFrom()
{
return pB[1];
}
char Packet::getAddTo()
{
return pB[2];
}
char Packet::getpDataSize()
{
return pB[3];
}
char Packet::getChecksum()
{
return pB[4];
}
char Packet::getEndP()
{
return pB[260];
}
char Packet::getData()
{
return pB[6 + pDataIndex];
}
void Packet::initClass()
{
pDataMax = 254;
pDataIndex = 0;
}
}
At this point i am just testing it so I just implemented two of the methods. When I try to run the program:
#include <iostream>
#include "Packet.h"
using namespace std;
Packet myPacket;
void buildPacket();
int main() {
buildPacket();
return 0;
}
void buildPacket( )
{
char startP = 0x28;
cout << "Setting startP!" << endl;
myPacket.setStartP(startP);
cout << "Getting startP" << endl;
cout << myPacket.getStartP() << endl;
cout << "Done";
}
The code is fine a compile/build time no issues there, it is a run time it falls over. This is really thruowing me, it really is making me doubt what I actually know about class creation and use in C++.
The program will run up to a certain point and then crashes with a windows message. on the console this is as far as it gets before crashing:
Setting startP!
in Set!Getting startP
(
As I can see it it seems to be on deletion that it crashes but not sure why. I looked around for similar issues but can't really find a reason why it is coming up with this, I would be grateful for some help on this one.
Don't call delete this in the destructor. The object is automatically destructed since it goes out of scope, no need for delete.
You can read more about it here: http://en.cppreference.com/w/cpp/language/scope