精华内容
下载资源
问答
  • QT 类静态函数作为回调函数

    万次阅读 2020-05-26 08:41:05
    (二) 今天使用静态函数作为回调函数,具体方式如下, (1) 在头文件中定义 class CardDataDispose : public QObject { Q_OBJECT public: static void callback(int device, int msg, i...

    (一) C++回调函数、静态函数、成员函数踩过的坑。
    明确一点即回调函数需要是静态函数。原因:
    普通的C++成员函数都隐含了一个this指针作为参数,这样使得回调函数的参数和成员函数参数个数不匹配。

    以前在使用回调函数的数据都是定义一个全局变量,把回调函数的返回结果给这个全局变量,然后在定时去刷新这个全局变量,这样虽然可以实现功能,但是方法不是很好 。

    (二) 今天使用类的静态函数作为回调函数,具体方式如下,
    (1) 在头文件中定义类
        class CardDataDispose : public QObject 
        {
            Q_OBJECT
        public:

            static void callback(int device, int msg, int param1, void *param2);//回调函数
            void data(QString cardID, QString cardAnswer);
        };
    (2) 在引用回调类的源文件中设置回调函数。
        TB_SetCallbackAddr(CardDataDispose::callback);
    (3) CardDataDispose回调函数的原型
        void CardDataDispose::callback(int device, int msg, int param1, void *param2)
        {
            CardDataDispose *a;
            a->data("1" , "2");

        }

        void CardDataDispose::data(QString cardID, QString cardAnswer)
        {
            引用回调函数的类
            UBBoardController *b;
            b->receiveCardData(cardID, cardAnswer);
        }
        
    (三) 通过以上把回调函数封装成一个类,在收到数据后直接调用receiveCardData()函数就可以传输数据,不需要开启定时器刷新了。

    展开全文
  • 单件是对类静态函数的一种改进,首先改变了全局变量对系统的污染,其次它可以有子类,可以定义虚函数,可以有子类,而的静态方法是不能定义为虚函数的,因此不具有多态性。单件模式可以扩展为多件,即允许有受控的...

    实用类提供系统公用的静态静态方法,并且也经常采用私有化的构造函数,与单件模式不同,它没有实例,其中的方法全部是静态方法。

    单件提供了全局唯一的访问入口,易于控制可能发生的冲突。单件是对类静态函数的一种改进,首先改变了全局变量对系统的污染,其次它可以有子类,可以定义虚函数,可以有子类,而类的静态方法是不能定义为虚函数的,因此不具有多态性。

    单件模式可以扩展为多件,即允许有受控的多个实例存在。

    另外,单件模式维护了自身的实例化,在使用时是安全的,类静态函数无法自行维护。

     还有,如果方法需要被多次执行,还是写成实例方法,通过生成类的实例来运行比较好。比如需要多次操作某个目录,可以实例化DirectoryInfo实例,然后再利用生成的实例操作;如果仅仅操作一次那就可以用Directoty类的静态方法。

    展开全文
  • 回调函数的使用封装在了callback.h中,main.cpp用于测试回调。 Ref CEGUI。。。   callback.h (回调封装) ######################...**Description: 回调函数机制封装(支持成员函数与全局函数) **Autor: by Roo

     

    回调函数的使用封装在了callback.h中,main.cpp用于测试回调。

    Ref  CEGUI。。。

     

    callback.h (回调封装)

    #######################################

    /*
    **FileName: callback.h
    **Description: 回调函数机制封装(支持类成员函数与全局函数)
    **Autor: by Roobt
    **Create Time: 2012/11/26   10:34
    */

    #ifndef __CALLBACK_H__
    #define __CALLBACK_H__

    #include <map>
    using std::map;
    using std::make_pair;

    typedef int EventArgs;
    typedef int EventID;

    //回调基类
    class SlotFunctorBase
    {
    public:
     virtual ~SlotFunctorBase() {};

     //使用操作符来调用函数
     virtual bool operator()(const EventArgs& args) = 0;
    };

    //全局函数、静态函数或类的静态成员函数做回调
    class FreeFunctionSlot : public SlotFunctorBase
    {
    public:
     //定义回调函数的格式
     typedef bool (SlotFunction)(const EventArgs&);  //函数指针

    public:
     FreeFunctionSlot(SlotFunction* func) : d_function(func)
     {}

     virtual bool operator()(const EventArgs& args)
     {
      return d_function(args);
     }

    private:
     SlotFunction* d_function;
    };

    //类的普通成员函数做回调
    template<typename T>
    class MemberFunctionSlot : public SlotFunctorBase
    {
    public:
     //!成员变量的回调函数定义
     typedef bool (T::*MemberFunctionType)(const EventArgs&);  //类的成员函数指针的类型

    public:
     MemberFunctionSlot(MemberFunctionType func, T* obj) :
     d_function(func), d_object(obj)
     {}

     virtual bool operator()(const EventArgs& args)
     {
      return (d_object->*d_function)(args);  //调用类的成员函数
     }

    private:
     MemberFunctionType d_function;
     T* d_object;
    };


    //对上面2种实现的封装
    class SubscriberSlot
    {
    public:
     //默认构造函数
     SubscriberSlot()
     {
      d_functor_impl = NULL;
     }

     //标准析构函数
     ~SubscriberSlot()
     {
      delete d_functor_impl;
      d_functor_impl = NULL;
     }

     //调用函数的()重载,具体由第一类Functor实现
     bool operator()(const EventArgs& args) const
     {
      return (*d_functor_impl)(args);
     }

     //返回成员是否有效,是否已经连接到一个具体的Functor实现
     bool connected() const
     {
      return d_functor_impl != NULL;
     }

     //FreeFunctionSlot,自由函数的封装类
     SubscriberSlot(FreeFunctionSlot::SlotFunction* func) :
     d_functor_impl(new FreeFunctionSlot(func))
     {}

     // 模板构造函数,以成员函数的封装为参数,MemberFunctionSlot。
     template<typename T>
     SubscriberSlot(bool (T::*function)(const EventArgs&), T* obj) :
     d_functor_impl(new MemberFunctionSlot<T>(function, obj))
     {}

    private:
     //内部基本Functor的指针,SlotFunctorBase基类的优势在这里用到了
     SlotFunctorBase* d_functor_impl;
    };

    // 注册函数宏
    // 注册全局函数、类静态成员函数作为回调函数

    #define  REGISTER_FUNC(id, subscribeSlot, func, q) \
     SubscriberSlot* subscribeSlot = new SubscriberSlot((FreeFunctionSlot::SlotFunction*)&func);\
     q->subscribe(id, subscribeSlot);

    // 注册类成员函数作为回调函数
    // param0: 事件id
    // param1: psubscribeSlot, 随便一个变量名
    // param2: func, 要注册的类的普通成员函数(即:回调函数)
    // param3: p, func所在类的一个实例指针
    // param4: q, 注册类(调用注册函数的类)的一个实例指针

    #define REGISTER_OBJFUNC(id, subscribeSlot, func, p, q) \
     SubscriberSlot* subscribeSlot = new SubscriberSlot(&func, p);\
     q->subscribe(id, subscribeSlot);

    // 回调
    class Callback
    {
    public:
     typedef map<EventID, SubscriberSlot*> EventMap;
     
    public:
     Callback() {eventList.clear();}
     ~Callback() {eventList.clear();}

     bool subscribe(EventID id, SubscriberSlot* subscriberSlot)
     {
      if (NULL == subscriberSlot)
       return false;
      EventMap::iterator iter = eventList.find(id);
      if (iter != eventList.end())
       return false;
      eventList.insert(make_pair(id, subscriberSlot));
      return true;
     }

     bool evoke(EventID id)
     {
      EventMap::iterator iter = eventList.find(id);
      if(iter == eventList.end())
       return false;
      SubscriberSlot* subscribeSlot = eventList[id];
      if (subscribeSlot)
      {
       EventArgs args = 0;
       (*subscribeSlot)(args);
       return true;
      }
      return false;
     }

    private:
     EventMap eventList;
    };

    #endif

     

    #######################################

     

    main.cpp (测试)

     ######################################

    #include "stdafx.h"
    #include "callback.h"
    #include <iostream>
    using namespace std;

    class A
    {
    public:
     bool Test1(const EventArgs&)
     {
      cout<<"Test1..."<<endl;
      return true;
     }
     static bool Test2(const EventArgs&)
     {
      cout<<"Test2..."<<endl;
      return true;
     }
    };

    class B : public Callback
    {
    public:
     enum EVENT_TYPE
     {
      EVENT_TYPE_INVALID = -1,
      EVENT_TYPE1,
      EVENT_TYPE2,
      EVENT_TYPE_NUMBER,
     };

    public:
     B(A *pA) : m_pAObj(pA)
     {}

     void registerCallback()
     {
      // 类成员函数
      REGISTER_OBJFUNC(EVENT_TYPE1, subscribeSlot, A::Test1, m_pAObj, this);
      // 类静态函数
      REGISTER_FUNC(EVENT_TYPE2, subscribeSlot2, A::Test2, this);
     }
     void evoke()
     {
      Callback::evoke(EVENT_TYPE1);
      Callback::evoke(EVENT_TYPE2);
     }

    private:
     A *m_pAObj;
    };

    // 主函数
    int _tmain(int argc, _TCHAR* argv[])
    {
     A *pA = new A();
     B *pB = new B(pA);
     if (pB)
     {
      pB->registerCallback();
      pB->evoke();
     }

     system("pause");
     return 0;
    }

    ######################################

    展开全文
  • 2)类静态函数,对比普通成员函数,没有this指针,不能访问非static成员。 3)要说二者相同点,都是c++名字控制的手段:全局静态函数被局限在一个编译单元,通俗的将就是在一个cpp文件中定义的全局静态函数在另一...
      
    

    1)全局静态函数只在本编译单元有效。
    2)类静态函数,对比普通成员函数,没有this指针,不能访问非static成员。
    3)要说二者相同点,都是c++名字控制的手段:全局静态函数被局限在一个编译单元,通俗的将就是在一个cpp文件中定义的全局静态函数在另一个cpp文件中不能被调用。例程如下;

    //   main.cpp
    #include   <iostream>

    extern   int   hello2();

    static   int   hello()
    {
            std::cout   < <   "hello,   world! "   < <   std::endl;
            return   0;
    }

    int   main()
    {
            hello();
            hello2();
    }

    //   append.cpp
    extern   int   hello();

    int   hello2()
    {
            hello();
    }
    //---------------------------------------------
    编译将产生错误:
    append.obj   :   error   LNK2001:   unresolved   external   symbol   "int   __cdecl   hello(void) "   (?hello@@YAHXZ)
    Debug/Test.exe   :   fatal   error   LNK1120:   1   unresolved   externals

    而把hello前面的static去掉之后就可以编译成功了。

    可见不能在append.cpp中调用main.cpp中的全局静态成员函数。 

    而类静态函数,必须使用其“类名::静态函数名”

    #include<iostream>
    using namespace std;
    class A
    {
    	public:
    	static void fun(int x)
    	{
    		
    		cout<<x<<endl;
    	}
    };
    int main()
    {
    	A son;
    	son.fun(5);
    //	A::fun(5);
    	return 0;
    }


    编译虽然会出结果,但是有一条警告,son未引用的局部变量,说明静态成员函数不可以用对象调用的。但是至于为什么会输出正确结果不太理解,望高手指教。也有待进一步研究。用//注释起来的也可以输出正确结果。

    我们把函数和变量声明为静态的有什么优点那,从静态变量的角度看,更容易理解一些
    使用静态数据成员可以节省内存,因为它是所有对象所公有的,因此,对多个对象来说,静态数据成员只存储一处,供所有对象共用。静态数据成员的值对每个对象都是一样,但它的值是可以更新的。只要对静态数据成员的值更新一次,就可以保证所有对象都能够访问到被更新后的值,这样可以提高效率和节省内存空间。这是静态变量的优点同时也是他的一个缺点,在类中声明了静态变量,无论用户使用使用这个类,而这个静态变量都会申请他需要的内存容量。
    对于多线程的情况下,访问静态变量我们需要加一些异步机制,防止多个线程同时修改静态变量。
    类内静态函数比全局静态函数的用处要多的多,在这里先讲简单的
    全局静态函数的应用比较常见的就是
    static   int   fun()
    {
    ...;
    return   1;
    }
    当我们希望在多个类中调用fun函数时,我们必须把fun声明为static类型,不然在link时编译器会发现多个关于fun的定义。这种函数的应用,多少带有C的色彩,尤其当我们在C环境写好的函数,移植到C++中时,需要在函数前面需要加上static,而如果我们需要移植多个函数时,更通用的一种方法是使用未命名名字空间
    namespace{
    int   fun()
    {
    ...;
    return   1;
    }

    }
    也许有人问如果在未命名名字空间中的函数再加上static修饰符号会怎么样?这个就完全取决以使用的编译器,可能会直接报错,也可能可以编译并正常使用。不过这样写,代码从语言层次上就很难移植编译环境,所以尽量不要这样写。
    关于这样的应用,在我从前的项目中实施过。当时我需要定义很多函数,执行三角形,已经像素转换方面的计算,所以把这些函数声明为static的。
    对于与全局静态函数,我们继续类内静态函数和静态变量的讨论,我想他们的应用是两者区别的最好体现。
    对于类内静态变量,我们需要在类外初始化,这是在使用静态变量需要注意的地方,有些初学者很容易在这里出错。类内静态变量使用最多的就是计算类的实例化个数。
    class   A
    {
    static   int   i;   //   外部初始化为0
    public:
    A()   //   构造函数
    {
    ++i;
    }
    ~A()   //   析构函数  
    {
    --i;
    }
    static   int   CreateObjectNumber()   //   或者创建对象的数目
    {
    return   i;
    }
    };

    也许读者认为这种方法,只是用来学习而已,实际很少使用。我不赞同这个观点。
    1:静态变量受public,protected   ,private限制,也就是如果静态变量是protected或者private类型的,在类外不能访问,比如
    A::i是错误的
    这条规则同样适用于静态函数
    2:静态变量在类内声明,而必须在类外初始化,模版类中应用也是这样。这里我们在static后面加上const类型,可以直接初始化。比如
    Class   A
    {
    //   Static   int   I   =   5;   //   error
    Static   const   int   I   =   5;   //   ok
    Int   m_list[I];
    }
    而这里I的应用也无非是Int   m_list[I];
    3:静态成员函数只能访问类的静态变量,而类的成员函数也可以访问类的静态变量,这样就可以通过静态成员变量建立类的静态成员函数和类对象的关联关系。
    4:还存在一种静态变量,他不是全局静态变量,而是函数内的静态变量,如下例中的i,这算是对全局静态变量的一种补充。
    int   fun()
    {
    static   int   i   =   3;
    ++i;
    return   i;
    }
    这种方式的好处时,只用调用fun函数时,静态变量i才申请内存,这也符合lazy   evaluation的设计要求。只有当需要时,才去申请。
    同样作为破坏封装的一种技术应用是友元函数或者友元类的应用,很多人形象比喻这种方式是在封装的物体上开了一个小小的洞,不提倡使用这种技术。其实任何技术都有他应用的场所,不然就不会出现这种技术。不过不去了解这种特性,也许永远我们不会知道这些技术的重要性。碰见这些技术也只会使用有色眼镜去看。友元函数的特征基本如下
    1) 必须在类的说明中说明友元函数,说明时以关键字friend开头,后跟友元函数的函数原型,友元函数的说明可以出现在类的任何地方,包括在private和public部分,不受private限制  
    2) 友元函数不是类的成员函数,所以友元函数的实现和普通函数一样,在实现时不用 ":: "指示属于哪个类,只有成员函数才使用 ":: "作用域符号;
    3) 友元函数不能直接访问类的成员,只能访问对象成员,所以在调用友元函数时,确保友元类的必须实例化。
    4) 友元函数可以访问对象的私有成员,但普通函数不行,这个需要注意,尤其是在友元类中,有时候发现两个类互相为友元类,确不能调用成员函数,就是这个原因。
    5) 调用友元函数时,在实际参数中需要指出要访问的对象,也可以把对象声明为全局对象而在友元函数中调用,当然在友元函数中可以调用其他全局函数,或者实例对象等操作。
    使用友员函数最大的优点就是,不用对类中的每个变量写Get/Set接口函数。尤其是当类中有大量的私有成员变量,而又不想为每个变量设置接口,同时又需要外部的某个函数调用。这样最好就是把这个函数声明为友元函数,我们在一些开源项目中很常见这种技术,比如阿agentx++。
    class   AU
    {
    public:
    AU(){
    };
    string   GetAU()
    {
    return   "Base--GetAU ";
    }
    virtual   string   GetAUU()
    {
    return   "Base--GetAUU ";
    };
    virtual   ~AU(){};
    };

    template   <class   T,class   TBase>
    class   TEMU:public   TBase
    {
    public:
    string   GetAA()
    {
    T*   pt   =   static_cast <T*> (this);
    return   pt-> GetA();   //   这里调用的是static   string   GetA()函数
    }

    string   GetBB()
    {
    T*   pt   =   static_cast <T*> (this);
    return   pt-> GetB();   //   这里调用的是string   GetB()
    }

    public:
    string   GetA()
    {
    return   "TEMU   -   GetA ";
    }

    string   GetB()
    {
    return   "TEMU   -   GetB ";
    }
    };

    class   DeriveTEMU   :   public   TEMU <DeriveTEMU,AU>
    {
    public:
    static   string   GetA()   //   注意这里是静态函数
    {
    return   "DeriveTEMU   -   GetA ";
    }
    string   GetB()
    {
    return   "DeriveTEMU   -   GetB ";
    }
    };

    测试用力
    DeriveTEMU   u;
    TEMU <DeriveTEMU,AU>   *p   =   &u;
    cout   < <   p-> GetAA()   < <   endl;
    cout   < <   p-> GetBB()   < <   endl;
    输出结果  
    DeriveTEMU   -   GetA
    DeriveTEMU   –   GetB
    在这里我们看到,调用类内静态函数的方式并不是简单的类名::函数的形式,而是通过模版父类调用子类静态函数,同样也给出了,调用普通函数的方式。这种机制可以理解为模版继承关系中的虚继承关系。当认识到模版中的静态函数使用,也许会更大的改变我们对静态函数的印象,这种机制在ATL,WTL中有广泛的应用,几乎每种涉及到消息影射关系的类中,都使用这种方式。

    展开全文
  • 静态函数只能访问的静态成员变量 静态函数只能访问的静态成员变量 静态函数只能访问的静态成员变量 静态函数只能访问的静态成员变量 转载于:...
  • C# 静态静态函数

    千次阅读 2016-07-30 15:53:47
    C# 翻译msdn文档 静态静态函数
  • 从声明方式来看: 普通成员函数是最一般的方法,即 class Foo: def plain_func(): pass 成员函数是 ...静态函数是 class Foo: @staticmethod def static_func(): pass 从调用方式来看,普通函数...
  • 程序最终都将在内存中执行,变量只有在内存中占有一席之地时才能被访问。  静态成员(变量和方法)属于... 在一个静态成员中去访问其非静态成员之所以会出错是因为在的非静态成员不存在的时候静态成员就
  • Python:普通成员函数、成员函数、静态函数 Python 中的也是一个普通对象,如果需要直接使用这个,例如将作为参数传递到其他函数中,又希望在实例化这个之前就能提供某些功能,那么最简单的办法就是使用 ...
  • 静态函数

    千次阅读 2019-05-14 16:29:20
    不会被访问或者修改任何对象数据成员,可声明为静态函数。 普通的静态函数只能在文件所在的编译单位内使用。静态函数没有this指针,不能被其他文件所用,其他文件中 可以定义相同名字的函数。 的静态成员函数...
  • 而调用中的静态函数,无需创建对象就可以调用了,因为当初始化的时候,就已经加载了静态函数,所以静态函数要比对象加载的早,对象只有被创建的时候才会在堆内存中创建空间。  另外,静态函数中不能使用非静态...
  • C++ (静态成员和静态函数)

    万次阅读 2018-07-21 15:01:46
    静态成员函数 class A { public: static int x; public: static void Func(){} } int A::x=10; 静态成员变量 a. 关键字static用于说明一个的成员变量时,该成员为静态成员。静态成员提供了一个同类对象...
  • 静态函数静态变量

    千次阅读 2010-07-26 09:40:00
    1.一个过多的静态函数静态变量,这个在多线程及多个实例以及继承里将难以实现
  • PYTHON中的函数、静态函数、成员函数以及变量、成员变量 Posted on 2019-03-16 15:10 Mr__Seven 阅读(14) 评论(0) 编辑 收藏 复制代码 1 class MethodDemo(): 2 classVar = ‘This is a class variable’ #...
  • 折磨了我好久的问题,还是自己c,c++功力不够,其实把自己的指针作为参数传入到静态函数中 就可以使用了。–,…….
  • 静态函数如何多态

    千次阅读 2015-04-24 14:53:49
    静态函数如何多态
  • 的静态成员变量,以及静态函数。 静态成员变量: 1.静态成员共享机制 2.静态成员局部属于,它不是对象的成员,位于静态区。 3.静态成员变量需要在外部进行初始化。 静态函数: 1.静态成员函数都在代码区,...
  • 在函数或者变量前面加上static修饰符号,以便把函数或者变量在内或者文件范围内共享,那么我们把这种函数和变量叫静态函数和静态变量。我们把函数和变量声明为静态的有什么优点那,从静态变量的角度看,更容易理解...
  • 今天在群里看了一个奇怪的代码。这样的代码是可以直接运行的 查看了编译以后的代码如下: ...接着就索性研究一下虚函数,成员函数静态成员函数。 把修改成如下。 执行代码如下:
  • C++提供static这个关键词对静态成员进行声明,静态成员函数的实例化无关,对于同一来说,静态成员函数是共享的。而普通成员函数需要实例化才能调用,对于每一个实例来说,普通成员函数是自己独有的。 #...
  • 静态函数, 函数, 成员函数的区别 本文地址: http://blog.csdn.net/caroline_wendy/article/details/23383995
  • 对象函数:对象函数直接在中声明即可,不需要添加装饰器,对象函数只能由对象调用执行,也可由调用,但是在调用时,需要将一个对象作为参数进行传递,对象函数中有一个self参数,self指调用该函数的对象,例如:...
  • C++ 类静态成员函数

    万次阅读 2020-12-06 18:25:14
    。。。
  • C#静态函数

    千次阅读 2019-07-09 22:48:51
    //一.新建Person ...面对对象静态函数和非静态函数的区别 { //新建个Person public class Person { private static string _name; //静态字段 public static string Name //属性,对字体的限定...
  • 类静态成员函数的定义

    千次阅读 2017-11-16 11:37:15
    类静态成员函数的定义
  • python 函数,实例函数,静态函数

    千次阅读 2018-05-16 00:25:48
    # 在定义中定义变量 cls_variable = "class varibale" def __init__(self): # 在构造函数中创建变量 self.__instance_variable = "instance variable" def instance_...
  • 当将的某个数据成员声明为static时,该静态数据成员只能被定义一次,而且要被同类的所有对象共享。各个对象都拥有中每一个普通数据成员的副本,但静态数据成员只有一个实例存在,与定义了多少的对象无关。静态...
  • link中可以调用abstrac中的静态函数,能不能把成员函数当成静态函数
  • 【 声明:版权所有,欢迎转载,请勿用于商业... 看过设计模式的朋友都知道,我们在设计单件模式的时候离不开静态函数。和的成员变量不同,的静态变量属于全部对象数据;同样和的成员函数不同,的静态函
  • 滚雪球学 Python 第二轮 已完成的文章清单 十五、函数、成员函数、静态函数、抽象函数、方法伪装属性 15.1 函数 @classmethod 15.2 静态函数 @staticmethod 15.3 函数与静态函数在继承中的表现 15.4 抽象...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,087,812
精华内容 435,124
关键字:

类静态函数