3

我正在尝试在 C++ 中创建某种事件处理程序。所以我有以下内容:

template<class W> 
delegate<W>* bind(W* obj, void (W::*f)(char*))
{
        return new delegate<W>(obj,f);
}

委托类和此功能完美运行。问题是如何存储绑定函数返回的委托对象?我知道使用 boost 和 c++ 11 很容易,但是不使用它们我怎么能解决这个问题呢?我确信它必须是可能的,因为在诸如 boost 和 c++11 之类的复杂事物之前它是可能的。

(他们也以某种方式在提升中做到了)。

所以我想做的是:

class Test1
{
    Test1(){}
    ~Test1(){}

    template<class W> 
    bind(W* obj, void (W::*f)(char*))
    {
            myCallBack = new delegate<W>(obj,f);
    }

    private:
        delegate * myCallBack;  //this does not work because I have to define the template but I dont know it know it could be anything

}

class Test2
{
    Test2()
    {
        Test1 t;
        t.bind(this, &Test2::callit);
    }
    ~Test2(){}
    void callit(char*)
    {
    }
}
4

2 回答 2

3

好的,我明白你到底需要什么。您只需要一个简单的回调运算符,具有固定的调用签名。

此示例演示如何针对您的特定情况完成:

#include <iostream>
#include <utility>
#include <type_traits>
#include <vector>
#include <algorithm>



struct Cb {
    virtual ~Cb(){}
    virtual void call(const char*) = 0;
};
template<class C>
struct CmCb : Cb {
    CmCb( C& c_, void (C::*fn_)(const char*) ) : c(c_),fn(fn_)
    {
    }
    virtual void call(const char* s) {
        (c.*fn)(s);
    }
    C& c;
    void (C::*fn)(const char*);
};

struct A {
    void foo( const char* s ) {
        std::cout<<s<<std::endl;
    }
};

class Test1
{
public:
    Test1(){}
    ~Test1(){delete cb;}

    template<class W> 
    void bind(W* obj, void (W::*f)(const char*))
    {
            cb=new CmCb<W>(*obj,f);
    }
    
    void callit(const char* s ){
        cb->call(s);
    }

    private:
        Cb* cb;
};

int main()
{
    Test1 t;
    
    A a;
    t.bind(&a, &A::foo );
    
    t.callit("hey");
}

如果您需要更复杂的解决方案(通用签名),那么您可以使用boost::any的某种类型擦除。

于 2013-10-17T20:18:32.253 回答
0

确实存在比原始标准 ( std::auto_ptr) 提供的更复杂的智能指针实现。但是它们都涉及一些更复杂的概念(主要是关于共享指针的引用计数)。使用这些有什么障碍?

如果您需要为环境提供更轻量级的智能指针实现,Andrei Alexandrescu 的Loki 库可能对您有用。我已经设法至少在有限的系统环境中无缝集成它(比使用 boost 更好、更容易)。

甚至不要尝试完全靠自己来做这件事,有很多陷阱......如果你能够启用标准,就使用这些!

于 2013-10-17T20:11:07.300 回答