如何使我的 C++ 类事件系统成为仅限于类型数组的模板类?

Posted

技术标签:

【中文标题】如何使我的 C++ 类事件系统成为仅限于类型数组的模板类?【英文标题】:How to make my C++ class event system be a template class limited to an array of types? 【发布时间】:2011-01-30 07:49:50 【问题描述】:

我想在类模板中使用 memcpy。因此,我的模板将仅限于任何指向 C POD(结构)和 char* 的链接(当然结构可以在其他独立类中声明)。我希望任何类都能够订阅它的函数(如果它有尊重的输入参数)来转换事件。所以我的班级现在看起来像:

class IGraphElement
    typedef void FuncCharPtr(char*, int) ;
public:
    void Add(FuncCharPtr* f)
    
        FuncVec.push_back(f);
    
    void CastData(char * data, int length)
        for(size_t i = 0 ; i < FuncVec.size(); i++)
            char* dataCopy = new char[length];
            memcpy(dataCopy, data, length);
            FuncVec[i](dataCopy, length);
        
    
private:
    vector<FuncCharPtr*> FuncVec ;
;

通常我想要两件真正合二为一的东西(我尝试用伪代码来解释):

template < typename GraphElementDatataStructurePtrType>
class IGraphElement
    typedef void FuncCharPtr(GraphElementDatataStructurePtrType, int) ;  // here I want FuncCharPtr to be  of type (AnyClassThatWantsToConnectToThisGraphElement::*)(GraphElementDatataStructurePtrType, int) 

public:
    void Add(FuncCharPtr* f)
    
        FuncVec.push_back(f);
    

    void CastData(GraphElementDatataStructurePtrType data, int length)
        for(size_t i = 0 ; i < FuncVec.size(); i++)
            GraphElementDatataStructurePtrType dataCopy = new GraphElementDatataStructurePtrType[length];
            memcpy(dataCopy, data, length);
            FuncVec[i](dataCopy, length);
        
    

private:
    vector<FuncCharPtr*> FuncVec ; 
  ;

我想要的东西有多大可能以及如何在我的课堂上实现它? (对不起 - 我是一个 c++ nube=()

【问题讨论】:

为什么要使用memcpy?为什么你使用new char[] 而不是std::vector&lt;char&gt;std::string,而其他类型也是如此? @GMan - 如果你能提供任何可能的代码来让我的课变得更好,我会很高兴看到它。但我的意思是复制指针内容并为订阅者保留和共享指针。顺便说一句,如果 boost 可以帮助我可以使用它... 您好,请进一步说明。据我了解,您想要完成两项任务:1)为任何可调用实体构建一个容器 2)使用提供的参数从该容器调用每个实体。我说的对吗? 【参考方案1】:

boost::signals 库已解决您的问题。 如果您对内部工作感兴趣,可以尝试使用 boost::function 和 boost::bind 库实现类似的功能。 您可以研究Modern C++ Design 以了解有关仿函数模板内部工作原理的详细信息,或者只是谷歌并询问这个论坛。

这是一个使用 boost 的解决方案代码sketch

void DataCastHelper (boost::funtion funcCharPtr, char * data, int length) 
   char* dataCopy = new char[length];
   memcpy(dataCopy, data, length);

   funcCharPtr(dataCopy, length);


class IGraphElement 
public:
    void Add (FuncCharPt* f) 
        funcVec.connect(boost::bind(&DataCastHelper, f, _1, _2));
    
    void CastData(char * data, int length)
        funcVec(data. length);
    

private:
    boost::signal<FuncCharPtr> funcVec;

传递给IGraphElement::Add 方法的FuncCharPt* f 参数与DataCastHelper 一起堆叠,以便为您处理数据。该信号处理仿函数的迭代和调用,并将参数传递给仿函数。

问候

【讨论】:

请注意,您可以使用 boost::bind 将几乎任何东西插入到信号中。示例:***.com/questions/768351/… 不-信号对我不起作用(请参阅***.com/questions/4844842/…)所以您能否提供有关如何执行我需要的操作的任何实用代码或某些特定书籍上有关如何执行此操作的任何特定页面东西? 我添加了一个简短的代码草图,描述了基于信号和函子的解决方案。如果您在“掌握它”方面遇到问题,您可能应该进一步研究仿函数的使用。我提到的 Alexandrescu 的书应该是一个很好的开始。 funcCharPtr typedef 会是什么样子? funcCharPtr 应该对应于您的信号模板专业化类型。所以它应该是 boost::function 或类似的东西。

以上是关于如何使我的 C++ 类事件系统成为仅限于类型数组的模板类?的主要内容,如果未能解决你的问题,请参考以下文章

如何使我的观点之一成为唯一的风景

C++ 事件系统 - 基于堆的事件触发

如何使我的事件在所有数据表页面上工作?

如何转换 Spark 数据框以使我的值成为列名? [复制]

iOS - 如何使我的视图不响应事件

Microsoft Graph API calendarView 是不是仅限于一个月?如何获取所有事件?