How to correctly initialize the pFuncton pointer?
#include <iostream>
class CTest
{
public:
void Function(int);
int (*pFuncton)(int);
void Test();
};
void CTest::Function(int Int)
{
std::cout << Int;
};
void CTest::Test()
{
pFuncton = Function;
pFuncton(1);
};
int main()
{
CTest test;
test.Test();
}
The type of the member function is void (CTest::*pFuncton)(int); and you need special syntax to call a member function via a member function pointer:
#include <iostream>
class CTest
{
public:
void Function(int);
void (CTest::*pFuncton)(int);
void Test();
};
void CTest::Function(int Int)
{
std::cout << Int;
};
void CTest::Test()
{
pFuncton = &CTest::Function;
(this->*pFuncton)(1);
};
int main()
{
CTest test;
test.Test();
}
Related
why gcc 9.4 not check parameters when bind a class member funtion to a std::function viriable, but check when bind a global function? here is example code, CreateRpcFun has a parameter, but Test member function print doesn't have any other parameters except this, bind print to CreateRpcFun works well, but global funtion print2 cannot, can anybody explain why?
#include <functional>
#include <iostream>
#include <string>
using namespace std;
using CreateRpcFun = std::function<void(const string &)>;
class Test {
public:
Test() : str_("nihao!") {}
// bind print to CreateRpcFun passed compile
void print() { cout << str_ << endl; }
private:
string str_;
};
class Holder {
public:
CreateRpcFun CreateRpc;
};
class Other {
public:
Other(Holder h, string str) : h_(h), str_(str) {}
void run() { h_.CreateRpc("world!"); }
private:
Holder h_;
string str_;
};
void print1(const string &str) { cout << str << endl; }
void print2() { cout << "magic" << endl; }
int main() {
Test t;
Holder h;
h.CreateRpc = std::bind(&Test::print, &t);
Other o(h, "hhhh");
o.run();
h.CreateRpc = &print1;
h.CreateRpc("test");
// h.CreateRpc = &print2; // compile error
// h.CreateRpc("test");
}
I have a request for function pointer by C++. below is the sample what I need:
in API file:
class MyClass {
public:
void function1();
void function2();
void function3();
void function4();
};
in main file:
MyClass globalglass;
void global_function_call(???)// <---- how to do declaration of argument???
{
//Do *function
}
int main()
{
global_function_call(&globalglass.function1()); // <---- pseudocode, I need to use global class
global_function_call(&globalglass.function2());
global_function_call(&globalglass.function3());
global_function_call(&globalglass.function4());
return 1;
}
I have no idea to do declaration...
To do what you are asking for, you can use a pointer-to-member-method, eg:
MyClass globalglass;
void global_function_call(void (MyClass::*method)())
{
(globalglass.*method)();
}
int main()
{
global_function_call(&MyClass::function1);
global_function_call(&MyClass::function2);
global_function_call(&MyClass::function3);
global_function_call(&MyClass::function4);
return 1;
}
Online Demo
I am using c++11 compiler.
I have two classes - class Test and class TestHelper.
The class Test is a friend-to-class TestHelper.
The class Test is only which we can access from outside.
Now, we want to call Test API i.e. setVal(). This setVal() should call
Test2 API i.e. setX and is expecting this pointer. I don't want to use this pointer but want
to use a smart pointer instead. How can I do so?
The notion of this kind of desirability is because of the fact that in reality, my class Test is pretty big. So, I am trying to make a helper class for Test i.e.
class TestHelper;
class Test
{
friend class TestHelper;
int x;
public:
void display() {
std::cout << x;
}
void setVal(int val) {
TestHelper testH;
testH.setX(this, 324);
}
};
class TestHelper
{
public:
void setX(Test *test, int val) {
/** some algorithm here and then change val to something else */
test->x = val*100;
}
};
int main()
{
std::cout << "Hello World!\n";
Test x;
x.setVal(130);
}
I tried changing the prototype from void setX(Test *test, int val)
to void setX(std::shared_ptr<Test> test, int val) but don't know how to pass this pointer
as std::shared_ptr<Test> test here.
So here is working solution with shared pointers. The example doesn't even compile due to missing definitions so you have to restructure your code into headers and cpp files.
Test.h:
#ifndef TEST_H
#define TEST_H
#include <memory>
#include "TestHelper.h"
class Test : public std::enable_shared_from_this<Test>
{
private:
friend class TestHelper;
int x;
public:
void display();
void setVal(int val);
};
#endif
Test.cpp:
#include <iostream>
#include "Test.h"
void Test::display() {
std::cout << x;
}
void Test::setVal(int val) {
TestHelper testH;
testH.setX(shared_from_this(), 324);
}
TestHelper.h:
#ifndef TESTHELPER_H
#define TESTHELPER_H
class Test;
class TestHelper
{
public:
void setX(std::shared_ptr<Test> test, int val);
};
#endif
TestHelper.cpp:
#include <memory>
#include "TestHelper.h"
#include "Test.h"
void TestHelper::setX(std::shared_ptr<Test> test, int val) {
/** some algorithm here and then change val to something else */
test->x = val*100;
}
main.cpp:
#include <iostream>
#include <memory>
#include "Test.h"
int main(void){
std::cout << "Hello World!\n";
auto x = std::make_shared<Test>();
x->setVal(130);
x->display();
}
You can run it here: https://paiza.io/projects/e/79dehCx0RRAG4so-sVZcQw
I don't understand why you want this, here's a few variants that compile
reference
// Reference variant
#include <iostream>
class Test;
class TestHelper
{
public:
void setX(Test & test, int val);
};
class Test
{
friend class TestHelper;
int x;
public:
void display() {
std::cout << x;
}
void setVal(int val) {
TestHelper testH;
testH.setX(*this, 324);
}
};
void TestHelper::setX(Test &test, int val)
{
/** some algorithm here and then change val to something else */
test.x = val*100;
}
int main()
{
Test x;
x.setVal(130);
x.display();
}
http://cpp.sh/7t3ec
shared ptr
// Shared ptr variant
#include <iostream>
#include <memory> // Required for shared_ptrs
class Test;
class TestHelper
{
public:
void setX(std::shared_ptr<Test> test, int val);
};
class Test : public std::enable_shared_from_this<Test>
{
friend class TestHelper;
int x;
public:
void display() {
std::cout << x;
}
void setVal(int val) {
TestHelper testH;
testH.setX(shared_from_this(), 324);
}
};
void TestHelper::setX(std::shared_ptr<Test> test, int val)
{
/** some algorithm here and then change val to something else */
test->x = val*100;
}
int main()
{
auto x = std::make_shared<Test>(); // x needs to be created as shared_ptr or it won't work
x->setVal(130);
x->display();
}
http://cpp.sh/87ao2
Perhaps with these you can refine your question?
I need to be able to specify a function for a class to be able to run (a callback function?) as part of a menu system, my knowledge of c++ is stretched here. Obviously this won't compile but hopefully it gives an idea of what I'm trying to do -
void testFunc(byte option) {
Serial.print("Hello the option is: ");
Serial.println(option);
}
typedef void (*GeneralFunction)(byte para);
GeneralFunction p_testFunc = testFunc;
class testClass {
GeneralFunction *functionName;
public:
void doFunction() {
functionName;
}
};
testClass test { *p_testFunc(123) };
void setup() {
Serial.begin(9600);
test.doFunction();
}
void loop() {
}
I am aware of some std:: options but Arduino doesn't have them implemented unfortunately.
Edit: The compiler output for this code -
sketch_mar10a:17:29: error: void value not ignored as it ought to be
testClass test { *p_testFunc(123) };
^
sketch_mar10a:17:35: error: no matching function for call to 'testClass::testClass(<brace-enclosed initializer list>)'
testClass test { *p_testFunc(123) };
^
Please find the below code, see if this helps,you need a constructer to take the parameter, also you can't call the function from the parameter list while its expecting a function pointer
#include <iostream>
using namespace std;
void testFunc(int option) {
std::cout<<"in fn "<<option;
}
typedef void (*GeneralFunction)(int para);
GeneralFunction p_testFunc = testFunc;
class testClass {
GeneralFunction functionName;
int param1;
public:
testClass(GeneralFunction fn,int par1):functionName(fn),param1(par1){}
void doFunction() {
functionName(param1);
}
};
testClass test (p_testFunc,123);
void setup() {
test.doFunction();
}
void loop() {
}
int main()
{
setup();
return 0;
}
Thanks to Bibin I have adapted his code to suit Arduino, separated the constructor, and initialized the class in setup().
void testFunc(byte option) {
Serial.print("Hello the option is: ");
Serial.println(option);
}
typedef void (*GeneralFunction)(byte para);
GeneralFunction p_testFunc = testFunc;
class testClass {
GeneralFunction functionName;
byte param1;
public:
testClass(GeneralFunction fn, int par1);
void doFunction() {
functionName(param1);
}
};
void setup() {
Serial.begin(9600);
testClass test (p_testFunc, 123);
test.doFunction();
}
void loop() {
}
testClass::testClass(GeneralFunction fn, int par1) //constructor
: functionName(fn), param1(par1) {}
Which outputs:
Hello the option is: 123
How do i pass a reference to a method through as a parameter? It might look something like this:
class Test
{
public:
Test();
void Bark();
void Bark2();
void TakesABark( void( &method )() );
}
// Start of procedure
Test::Test()
{
this->TakesABark(Test::Bark);
this->TakesABark(Test::Bark2);
}
void Test::Bark()
{
}
void Test::Bark2()
{
}
// Receives a variety of references to methods
void Test::TakesABark( void( &method )() )
{
// Calls a third party api that would look like this:
// Barbera::DoThatThingILike(Test::Bark2);
}
class Test
{
public:
Test();
void Bark();
void TakesABark(void (Test::*method)());
};
Test::Test()
{
this->TakesABark(&Test::Bark);
}
Sample code :
http://coliru.stacked-crooked.com/a/9351a79c20097035
#include <iostream>
#include <string>
#include <vector>
class Test
{
public:
Test();
void Bark();
void TakesABark( void(Test::*method)() );
};
Test::Test()
{
this->TakesABark(&Test::Bark);
}
void Test::Bark()
{
std::cout << "Bark";
}
void Test::TakesABark( void(Test::*method)() )
{
(this->*method)();
}
int main()
{
Test t;
}