查看完整版本 : c++ function pointer in a Class

煙民母親生賤種 2020-1-13 03:39 AM

c++ function pointer in a Class

[url]https://paiza.io/projects/Ksi9Irunrz12OyoNIxhJvA?language=cpp[/url]

條 link 有哂 code。

問題是如果把一個 class 內的 function pointer , 用另一個 class 內的實體 function assign 比佢,就出 error: reference to non-static member function must be called。但如果在用把實體 function 放在 global 內,然後才 assign 比 class 內的 function pointer 就無問題。可惜咁樣做會無左規劃性。有無人可以解決到。

前提係唔想用 work around, 例如把 function pointer 用個 class wrap 住去代替。

:fst_004::fst_004::fst_004:

煙民母親生賤種 2020-1-13 10:57 PM

 如上面條 Link 唔得,去呢條


[url]http://cpp.sh/9igw5n[/url]

煙民母親生賤種 2020-1-13 11:09 PM

[url]https://www.mycompiler.io/new/cpp?fork=EJwQ6L5[/url]

jasonchan35 2020-1-14 05:24 PM

一般 function pointer 只可以指去 global function / class static function
你想做既係 pointer to member function


#include <iostream>
#include <string>

class MyObject {
public:
    int func(int a) { std::cout << a; }
};

using MemFuncPointer = int(MyObject::*)(int);

int main()
{
    MemFuncPointer f = &MyObject::func;

    MyObject obj;        
    obj.func(10);   
}

[url=http://cpp.sh/5zpyx]http://cpp.sh/5zpyx[/url]

[url=https://www.tutorialspoint.com/function-pointer-to-member-function-in-cplusplus]https://www.tutorialspoint.com/function-pointer-to-member-function-in-cplusplus[/url]

煙民母親生賤種 2020-1-14 07:12 PM

但係你個例子個 f  果行無用過。即係同 Function point er  無關係。

jasonchan35 2020-1-15 05:44 PM

Sorry, 漏左

[url=http://cpp.sh/7xdto]http://cpp.sh/7xdto[/url]

#include <iostream>
#include <string>

class MyObject {
public:
        int func(int a) {
            std::cout << a;   
    }
};

using MemFuncPointer = int(MyObject::*)(int);

int main()
{
    MemFuncPointer f = &MyObject::func;

    MyObject obj;
    (obj.*f)(12);
}

kormer 2020-1-16 07:27 PM

都幾好玩。
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;

class A {
                public:
                int add(int a, int b) {
                        return a + b;
                }
                int sub(int a, int b) {
                        return a - b;
                }
                typedef int(A::*pt)(int,int);
};

class B {
        public:
                A::pt func;
};

int main() {
        A a;
        B b;
        int r=0,r1=0;
        srand((unsigned) time(0));
        r=rand();r1=rand();
        b.func = r%2==0?&A::add:&A::sub;
        A::pt p = r1%2==0?&A::add:&A::sub;
        cout << (a.*(b.func))(28333,5) << endl;
        cout << (a.*p)(28333,5) << endl;
}

煙民母親生賤種 2020-1-16 10:23 PM

function pointer  有個壞處,就係始終要受制於 signature  ,唔可以百撘。要百搭就一定要用  Interface  , class 之類掟入去。仲要自己寫 Implement 。

jasonchan35 2020-1-17 01:17 PM

你想要點百搭法 ?
可以 bind global function 同 member function ?

好多人都整 delegate, boost 都好似有
[url=http://www.cplusplus.com/forum/general/95365/]http://www.cplusplus.com/forum/general/95365/[/url]
[url=https://nikitablack.github.io/2016/04/12/Generic-C-delegates.html]https://nikitablack.github.io/2016/04/12/Generic-C-delegates.html[/url]

煙民母親生賤種 2020-1-17 07:38 PM

[quote]原帖由 [i]jasonchan35[/i] 於 2020-1-17 01:17 PM 發表 [url=https://www.discuss.com.hk/redirect.php?goto=findpost&pid=513156262&ptid=28813325][img]https://www.discuss.com.hk/images/common/back.gif[/img][/url]
你想要點百搭法 ?
可以 bind global function 同 member function ?

好多人都整 delegate, boost 都好似有
[url]http://www.cplusplus.com/forum/general/95365/[/url]
[url]https://nikitablack.github.io/2016/04/12/Generic-C-delegates.html[/url] ... [/quote]

例如 void (*fp)()  , 個 type  就無東西 return,  亦唔可有參數掟入去。如果用戶要 Int fn(int,int),  咁以經唔得。更何況有更複雜的情況, function 千變萬化的時候。

jasonchan35 2020-1-17 08:30 PM

唔係好明, 你係想一個 delegate 可以 support 唔同 function signature ?
咁點做到 type safe function call ?
或者可以用 string 做 message

如果唔係既話, delegate 可以用 template 做, 就可以唔同 parameter or return type

定你有無例子, 示範到你想點用 ?

[[i] 本帖最後由 jasonchan35 於 2020-1-17 08:37 PM 編輯 [/i]]

煙民母親生賤種 2020-1-19 03:40 AM

[quote]原帖由 [i]jasonchan35[/i] 於 2020-1-17 08:30 PM 發表 [url=https://computer.discuss.com.hk/redirect.php?goto=findpost&pid=513171873&ptid=28813325][img]https://computer.discuss.com.hk/images/common/back.gif[/img][/url]
唔係好明, 你係想一個 delegate 可以 support 唔同 function signature ?
咁點做到 type safe function call ?
或者可以用 string 做 message

如果唔係既話, delegate 可以用 template 做, 就可以唔同 parameter or return type

定你有無例子, 示範到你想點用 ? ... [/quote]好似 timer 咁。:fst_011:
[url]https://computer.discuss.com.hk/viewthread.php?tid=28823903&extra=page%3D1[/url]

form5 2020-1-20 07:19 AM

:lol :lol :lol
果然 

jasonchan35 2020-1-20 06:52 PM

咁 lambda 已經可以 capture 唔同 variable 再 pass 入去啦

[url=http://cpp.sh/526qx]http://cpp.sh/526qx[/url]

#include <iostream>
#include <string>
#include <functional>

void call_func(std::function<void(double time)> f) {
    f(1.23);
}

int main()
{
    int a = 1;   
    int b = 2;

    call_func([a](double time){
        std::cout << "time=" << time << " a=" << a << "\n";
    });

    call_func([a,b](double time){
        std::cout << "time=" << time << " a=" << a << ", b=" << b << "\n";
    });

}

煙民母親生賤種 2020-1-21 12:28 AM

[quote]原帖由 [i]jasonchan35[/i] 於 2020-1-20 06:52 PM 發表 [url=https://www.discuss.com.hk/redirect.php?goto=findpost&pid=513281252&ptid=28813325][img]https://www.discuss.com.hk/images/common/back.gif[/img][/url]
咁 lambda 已經可以 capture 唔同 variable 再 pass 入去啦

[url]http://cpp.sh/526qx[/url]

#include <iostream>
#include <string>
#include <functional>

void call_func(std::function<void(double time)> f) {
    f(1.23 ... [/quote]

你呢個係勉強做到。但一複雜時唔知有乜其他問題。而且好似散收收咁。又要用 Global  Scope。 同 oop  似乎不配。

jasonchan35 2020-1-21 11:38 PM

哦.. 咁都做到呀, 只係多少少功夫, 不過做一次就好

[url=http://cpp.sh/3tzpm]http://cpp.sh/3tzpm[/url][code]#include
#include

template class MyDelegate;

template
class MyDelegate {
public:
MyDelegate() = default;
MyDelegate(const MyDelegate& r) { operator=(r); }

void operator=(const MyDelegate& r) {
_func = r._func ? r._func->clone(_funcBuf) : nullptr;
}

MyDelegate(RETURN_TYPE(*fn)(ARGS...)) {
_func = StaticFunctor::s_create(_funcBuf, fn);
}

template
MyDelegate(OBJ* obj, RETURN_TYPE(OBJ::*fn)(ARGS...)) {
_func = MemberFunctor::s_create(_funcBuf, obj, fn);
}

RETURN_TYPE invoke(const ARGS&... args) {
if (_func) _func->invoke(args...);
}

private:
struct IFunctor {
virtual ~IFunctor() = default;
virtual IFunctor* clone(char* buf) = 0;
virtual RETURN_TYPE invoke(const ARGS&... args) = 0;
};

struct StaticFunctor : IFunctor {
using Func = RETURN_TYPE(*)(ARGS...);

static IFunctor* s_create(char* buf, Func f) {
auto* p = new(buf) StaticFunctor;
p->_func = f;
return p;
}

IFunctor* clone(char* buf) override { return s_create(buf, _func); }

RETURN_TYPE invoke(const ARGS&... args) override {
_func(args...);
}

Func _func = nullptr;
};

template
struct MemberFunctor : IFunctor {
using Func = RETURN_TYPE(OBJ::*)(ARGS...);

IFunctor* clone(char* buf) override { return s_create(buf, _obj, _func); }

static IFunctor* s_create(char* buf, OBJ* obj, Func f) {
auto* p = new(buf) MemberFunctor;
p->_obj = obj;
p->_func = f;
return p;
}

RETURN_TYPE invoke(const ARGS&... args) override {
(_obj->*_func)(args...);
}

OBJ* _obj = nullptr;
Func _func = nullptr;
};

struct Foo {};

IFunctor* _func = nullptr;
char _funcBuf[sizeof(MemberFunctor)];
};

class MyTimer {
public:
using Delegate = MyDelegate;

void fire() {
for (auto& f : delegates) {
f.invoke(1.23);
}
}

std::vector delegates;
};

void g_func(double x) {
std::cout << "g_func(" << x << ")\n";
}

class MyTest {
public:
void func(double x) {
std::cout << "MyTest::func(" << x << ")\n";
}
};

int main()
{
MyTimer timer;

MyTest obj;

timer.delegates.emplace_back(&g_func);
timer.delegates.emplace_back(&obj, &MyTest::func);

timer.fire();
}[/code]

kormer 2020-1-24 10:46 PM

可以咁玩。

#include <iostream>
#include <functional>
#include<string>

using namespace std;

class A {
        public:
                function<void(void)> func;
                void setFunc(function<void(void)> y) {
                        func = y;
                }
                void runfuncpt() {
                        func();
                        func();
                }
};

class B {
        public:
                A a;
                template <typename T>
                T addAny(T one, T other) { return one + other;}

                void f() {
                        cout << "any function from Class B run by Class A:" << endl;
                        cout << addAny(32233,5) << endl;
                        cout << addAny<double>(32233.0,5.8) << endl;
                        cout << addAny(32333.1,55.7) << endl;
                        string s1("dis");
                        string s2("cuss");
                        string s3(" hk");
                        cout << addAny(s1,addAny(s2,s3)) << endl;
                }

                B() {
                a.setFunc(bind(&B::f,this));
                }

                void run() {
                        a.runfuncpt();
                }
};

int main() {
        B b;
        b.run();
}

煙民母親生賤種 2020-1-24 11:59 PM

 B() {
                a.setFunc(bind(&B::f,this));
                }


呢句顯示出個結構有一個問題。就係  Coupling,  或者叫 has A 。唔知有乜方法可解決。如果一個 Class  , 唔知將來會用到什麼物件,但當要用時又可動態加入去。我唯一想到既方法,就係用 polymorph ism 。即係我果d code  用 derived class  加進去。

kormer 2020-1-25 01:29 AM

我想這個看系統的要求呢,簡單的hello world 類型程式都可以用structured或oo導向編程,但簡單直接的東西用太多類我或會認為這是過於複雜,或會影響執行效能吧。條條大道通羅馬呢。

Btw,新年快樂 :-)
頁: [1]
查看完整版本: c++ function pointer in a Class