#include <iostream>
struct A {
explicit A(int a) : _a(a) {};
int _a;
};
struct ClassFunction {
ClassFunction(std::shared_ptr<A> myA) : _myA(myA) {}
double operator() (int &x,
int &g) {
return 1.0
+ static_cast<double>(_myA->_a); // offending line
}
static double wrap(int x, int g, void *data) {
return (*reinterpret_cast<ClassFunction*>(data)) (x,g);
}
std::shared_ptr<A> _myA;
};
int main() {
int x = 1;
int g;
auto myA = std::shared_ptr<A>(new A(int(20)));
ClassFunction myClassFunction(myA);
std::cout << ClassFunction::wrap(x,g,NULL) << std::endl;
return 0;
}
I'm trying to create a function object class ClassFunction that takes a std::shared_ptr<A> as a parameter, which I then call via the static member function ClassFunction::wrap.
If I access a data member of A as myA->_a the program fails to run (it does compile without any complaint, however).
How do I make this work?
Try the following:
std::cout << ClassFunction::wrap(x, g, &myClassFunction) << std::endl;
reinterpret_cast< ClassFunction*>(data) is applicable when the data points to instance of ClassFunction class.
Related
If I have a friend function can I somehow use set() to assign a value to a private variable inside the function? Or some other method?
Example : Here I have 3 private variables. I tried to make the sum of 2 of them and store the result in the 3rd one. I tried to do it with a setter but the result is 0. In main it works, but I don't know if I can make it work in the class function.
#include <iostream>
using namespace std;
class Function{
private:
int a;
int b;
int sum;
public:
Function() = default;
Function(int _a, int _b);
friend int sumNumber(Function f);
//Setter and getter
int getA() const;
void setA(int a);
int getB() const;
void setB(int b);
int getSum() const;
void setSum(int sum);
};
Function::Function(int _a, int _b) {
this->a = _a;
this->b = _b;
}
int Function::getA() const {
return a;
}
void Function::setA(int a) {
Function::a = a;
}
int Function::getB() const {
return b;
}
void Function::setB(int b) {
Function::b = b;
}
int Function::getSum() const {
return sum;
}
void Function::setSum(int sum) {
Function::sum = sum;
}
int sumNumber(Function f) {
int a = f.getA();
int b = f.getB();
int sum = a + b;
f.setSum(sum);
return sum;
};
int main() {
Function AA(1,2);
cout << sumNumber(AA);
cout << " " << AA.getSum();
AA.setSum(sumNumber(AA));
cout << "\n" << AA.getSum();
return 0;
}
Output :
3 0
3
As alluded to in the comments, the issue is with this function:
int sumNumber(Function f) {
int a = f.getA();
int b = f.getB();
int sum = a + b;
f.setSum(sum);
return sum;
};
Let us walk through your code:
Function AA(1,2);
You create a object of type Function, called AA and you allocate each member variable of that object via the constructor (1 and 2).
cout << sumNumber(AA);
You call your method (sumNumber) and pass to it a copy of your variable AA. That function adds the two numbers together and internally calls setSum.
cout << " " << AA.getSum();
You now try to display the sum value by calling the getSum method. But the issue was that you passed a copy of your variable into the sumNumber function. The original AA variable was left alone.
To fix this you need to adjust your function by adding an ampersand &. Like this:
int sumNumber(Function& f) {
int a = f.getA();
int b = f.getB();
int sum = a + b;
f.setSum(sum);
return sum;
};
Now your variable AA is being passed by reference and not by value. There are lots of tutorials about this concept.
I have a function object definition:
struct BaseFunctor
{
std::string desc = "Not this one!";
virtual double operator()(double a, double (*func) (double)) = 0;
};
and a set of derived function object definitions:
struct DerivedFunctor1 : public BaseFunctor
{
std::string desc = "Yes this!";
virtual double operator()(double a, double (*func) (double))
{
return a * func(a);
}
};
struct DerivedFunctor2 : public BaseFunctor
{
std::string desc = "This is also correct!";
virtual double operator()(double a, double (*func) (double))
{
return 5 * a * func(a);
}
};
They are instantiated and used in the following way:
double f1(double x){
return x*x+x;
}
template <typename T, typename F>
void do_something(T &func, F &derived)
{
double a = 1.0;
double res = derived(a, func);
std::cout << derived.desc << std::endl;
std::cout << "Result is: " << res << std::endl;
}
int main()
{
std::vector<BaseFunctor*> functors;
DerivedFunctor1 *derived1 = new DerivedFunctor1;
DerivedFunctor2 *derived2 = new DerivedFunctor2;
functors.push_back(derived1);
functors.push_back(derived2);
for (auto &f : functors)
{
do_something(f1, *f);
}
}
Now, the reason that the two function objects are derived from BaseFunctor was so I could collect them in a standard container and iterate through them. Are there other and more efficient ways to iterating through function objects?
Secondly, running the code outputs
Not this one!
Result is: 2
Not this one!
Result is: 10
When I try to access the member variable desc, I get the member variable of the parent class. I could write getters and get access to the member variables of the derived function objects in that way but that seems like a lot of work if there are many member variables to the function objects. Are there any other way of achieving this?
Your derived classes define another member named desc in addition to existing BaseFunctor::desc.
What you rather need is to initialize BaseFunctor::desc with the correct string. Example:
#include <iostream>
#include <memory>
#include <vector>
struct BaseFunctor {
std::string const desc;
virtual double operator()(double a, double (*func) (double)) = 0;
virtual ~BaseFunctor() noexcept = default;
protected:
BaseFunctor(std::string desc) noexcept
: desc(move(desc))
{}
};
struct DerivedFunctor1 : public BaseFunctor {
DerivedFunctor1() : BaseFunctor("Yes this!") {}
double operator()(double a, double (*func) (double)) override { return a * func(a); }
};
struct DerivedFunctor2 : public BaseFunctor {
DerivedFunctor2() : BaseFunctor("This is also correct!") {}
double operator()(double a, double (*func) (double)) override { return 5 * a * func(a); }
};
template <typename T>
void do_something(T &func, BaseFunctor &derived) {
double a = 1.0;
double res = derived(a, func);
std::cout << derived.desc << '\n';
std::cout << "Result is: " << res << '\n';
}
double f1(double a) noexcept { return a * a + a; }
int main() {
using P = std::unique_ptr<BaseFunctor>;
std::vector<P> functors;
functors.push_back(P(new DerivedFunctor1));
functors.push_back(P(new DerivedFunctor2));
for (auto &f : functors)
do_something(f1, *f);
}
A few other changes:
BaseFunctor must have a virtual destructor if objects of derived classes get deleted through BaseFunctor*, and your code suggests that.
Derived classes overridden functions should use override instead of virtual for the compiler to catch errors if you try to override a function that doesn't exists or have different parameters and/or return type. With virtual it introduces a new function overload with the same name, in this case.
std::unique_ptr is used to avoid manual cleanup and leaking memory.
BaseFunctor::desc made const, so that it must be initialized in the initializer list in BaseFunctor. That also makes BaseFunctor non-copyable and non-movable, which avoids accidental copy of derived class objects with slicing.
Sample for calling a constant number of functions with the same parameters, as discussed in comments. See the (overloaded) function call_all:
#include <iostream>
void call_all() {
// Does nothing, just stops the recursion.
}
template<typename Current, typename... Args>
void call_all(Current current_function, Args... args) {
current_function();
call_all(args...);
}
void func1() {
std::cout << "func1" << std::endl;
}
void func2() {
std::cout << "func2" << std::endl;
}
int main() {
// Pass anything that implements operator() here.
call_all(func1, func2);
}
I am trying to associate a struct's member variable with a class. So that when I create a new class, I can specify that it is associated with this member variable in a struct. For example:
struct A {
int a;
int b;
};
static A a[2];
a[0].a = 1;
a[0].b = 2;
a[1].a = 3;
a[1].b = 4;
class foo {
public:
foo(int index, ???) {
c = a[index].???; //Is it possible to define the 2nd parameter as a getter of struct A's member? So this line could resolve to either a[index].a or a[index].b?
}
private:
int c;
};
So that:
new foo(0, ???) would set c to 1 given ??? refer to A::a
new foo(0, ???) would set c to 2 given ??? refer to A::b
new foo(1, ???) would set c to 3 given ??? refer to A::a
new foo(1, ???) would set c to 4 given ??? refer to A::b
Yes, it is possible, you need to pass a data member pointer:
#include <iostream>
struct A
{
int a;
int b;
};
static A a[2]
{
1, 2
, 3, 4
};
class foo
{
public: int c;
public:
foo(int const index, int A::* const p_field)
{
c = a[index].*p_field;
}
};
int main()
{
foo const f1(0, &A::a);
::std::cout << f1.c << ::std::endl;
foo const f2(0, &A::b);
::std::cout << f2.c << ::std::endl;
foo const f3(1, &A::a);
::std::cout << f3.c << ::std::endl;
foo const f4(1, &A::b);
::std::cout << f4.c << ::std::endl;
return 0;
}
Check this code at online compiler
You have a couple options. If you just want the integer (like you have in your code you've posted), then just take an integer as a parameter to the constructor and pass it the right number.
class foo {
public:
foo(int val) {
c = val
}
private:
int c;
};
int main() {
foo f(a[0].b);
}
Or you could take a reference to an integer. This way if one changes, the other will as well:
class foo {
public:
foo(int &val) : c(val) { } //need to use an initialization list for this one
private:
int &c;
};
int main() {
foo f(a[0].b);
a[0].b = -1; //f.c will be -1 now as well
}
Using a data member pointer as in VTT's answer is the most direct solution but I often find member pointers and member function pointer syntax a bit cumbersome and I believe it is hard for the compiler to optimize.
For these kind of things I prefer to use a stateless lambda. You can pass a lambda to a function template and then the compiler can easily optimize it away:
#include <iostream>
struct A {
int a;
int b;
};
static A a[2]{{1, 2}, {3, 4}};
class foo {
public:
int c;
public:
template<typename F>
foo(int index, F getter) { c = getter(a[index]); }
};
int main() {
auto agetter = [](const A& a){ return a.a; };
auto bgetter = [](const A& a){ return a.b; };
foo const f1(0, agetter);
std::cout << f1.c << "\n";
foo const f2(0, bgetter);
std::cout << f2.c << "\n";
foo const f3(1, agetter);
std::cout << f3.c << "\n";
foo const f4(1, bgetter);
std::cout << f4.c << "\n";
}
I'd like to call a few methods of classes 'A' and 'B' from the class 'Caller'. I need to use a function pointer because I want to call different methods.
My method gets called, but when I try to access a member variable from it, my program crashes ('program.exe has stopped working').
How come that happens?
#include <iostream>
using namespace std;
template <class T>
class Caller
{
typedef void (T::*myFunc)(int);
public:
Caller(T* obj, myFunc fp)
{
f = fp;
}
void invoke(int foobar)
{
(o->*f)(foobar);
}
private:
myFunc f;
T* o;
};
class A
{
public:
A() : n(0) {}
void foo(int bar)
{
cout << "A::foo called (bar = " << bar << ", n = " << n << ")" << endl; // the crash occurs here, and 'this' equals 0 at this point
}
void setNum(int num)
{
n = num;
}
private:
int n;
};
class B
{
public:
B() : n(0) {}
void fooo(int bar)
{
cout << "B::fooo called (bar = " << bar << ", n = " << n << ")" << endl; // same here if I call B::fooo first
}
void setNum(int num)
{
n = num;
}
private:
int n;
};
int main()
{
A myA;
B myB;
myA.setNum(128);
myB.setNum(256);
Caller<A> cA(&myA, &A::foo);
Caller<B> cB(&myB, &B::fooo);
cA.invoke(10);
cB.invoke(20);
return 0;
}
Thank you in advance.
EDIT : I use VS2017 and I can build my program without getting any compiler errors.
My method gets called, but when I try to access a member variable from it, my program crashes ...
Because you forgot to assign passed obj to o pointer in your Caller:
template <class T>
class Caller
{
typedef void (T::*myFunc)(int);
public:
Caller(T* obj, myFunc fp)
{
o = obj; // << == you need this!
f = fp;
}
void invoke(int foobar)
{
(o->*f)(foobar);
}
private:
myFunc f;
T* o;
};
Also, in general it's better to use member initializer lists:
Caller::Caller(T* obj, myFunc fp) : o(obj), f(fp)
{
}
I'll describe my question using the following sample code.
I have class B defined as follows:
class B
{
public:
inline B(){}
inline B(int(*f)(int)) :myfunc{ f }{}
void setfunction(int (*f)(int x)) { myfunc = f; }
void print(int number) { std::cout << myfunc(number) << std::endl; }
private:
int(*myfunc)(int);
};
I then define class A as follows:
class A
{
public:
A(int myint) :a{ myint }{ b.setfunction(g); }
int g(int) { return a; }
void print() { b.print(a); }
private:
B b;
int a;
};
To me the issue seems to be that the member function g has the signature int A::g(int) rather than int g(int).
Is there a standard way to make the above work? I guess this is quite a general setup, in that we have a class (class B) that contains some sort of member functions that perform some operations, and we have a class (class A) that needs to use a particular member function of class B -- so is it that my design is wrong, and if so whats the best way to express this idea?
You can use std::function:
class B
{
public:
inline B() {}
inline B(std::function<int(int)> f) : myfunc{ f } {}
void setfunction(std::function<int(int)> f) { myfunc = f; }
void print(int number) { std::cout << myfunc(number) << std::endl; }
private:
std::function<int(int)> myfunc;
};
class A
{
public:
A(int myint) :a{ myint } {
b.setfunction([this](int a) {
return g(a);
}
);
}
int g(int) { return a; }
void print() { b.print(a); }
private:
B b;
int a;
};
You could generalize the class B. Instead of keeping a pointer (int(*)(int)), what you really want is any thing that I can call with an int and get back another int. C++11 introduced a type-erased function objection for exactly this reason: std::function<int(int)>:
class B
{
using F = std::function<int(int)>
public:
B(){}
B(F f) : myfunc(std::move(f)) { }
void setfunction(F f) { myfunc = std::move(f); }
void print(int number) { std::cout << myfunc(number) << std::endl; }
private:
F myfunc;
};
And then you can just provide a general callable into B from A:
A(int myint)
: b([this](int a){ return g(a); })
, a{ myint }
{ }
Use std::function and std::bind
class B
{
public:
inline B(int(*f)(int)) :myfunc{ f }{}
void setfunction(std::function<int(int)> f) { myfunc = f; }
void print(int number) { std::cout << myfunc(number) << std::endl; }
private:
std::function<int(int)> myfunc;
};
// ...
A a;
B b(std::bind(&A::g, &a));
Also note that you should initialize the function pointer to some default value (most likely null) and check for it when using, otherwise it's value is undefined.
You could use std::bind to bind the member function A::g.
class B
{
public:
inline B(){}
inline B(std::function<int(int)> f) :myfunc{ f }{}
void setfunction(std::function<int(int)> f) { myfunc = f; }
void print(int number) { std::cout << myfunc(number) << std::endl; }
private:
std::function<int(int)> myfunc;
};
class A
{
public:
A(int myint) :a{ myint } {
b.setfunction(std::bind(&A::g, this, std::placeholders::_1));
}
int g(int) { return a; }
void print() { b.print(a); }
private:
B b;
int a;
};
Note you need to change the type of functor from function pointer to std::function, which is applicable with std::bind.
LIVE