Qt_log2000_信号与槽中的connect函数之深入part1
来源:互联网 发布:社会经济发展数据库 编辑:程序博客网 时间:2024/06/10 20:31
Qt学习记录5
Qt; C++ 11; Qt父子窗体; Qt父子窗体间信息传递; Qt信号与槽; 函数指针;
学习Qt将近2个月了,现在对学习所得进行记录。本文是log2000计划的一部分
实验环境:
Qt5.8.0 支持C++ 11
ubuntu 14.04 64bit
在记录connect函数之前,现需要一些预备知识。
①成员函数指针
首先看一段代码
#include <iostream>using namespace std;class Person { public: void sayHello(){ cout<<"你好"<<" "; printf("%d\n",&Person::sayHello); } virtual void sayName(){ cout<<"我没有名字"<<" "; printf("%d\n",&Person::sayName); }};class Child : public Person { public: void sayHello(){ cout<<"你好"<<" "; printf("%d\n",&Child::sayHello); } virtual void sayName(){ cout<<"我是小明"<<" "; printf("%d\n",&Child::sayName); }};typedef void (*FunctionPointer)();typedef void (Person::*PersonMemberFunctionPointer)();typedef void (Child::*ChildMemberFunctionPointer)();void runfuncName(Person * obj, void (Person::*func)() ){//PersonMemberFunctionPointer func (obj ->* func)();}int main(int argc, char *argv[]){ Person someone; Child xiaoming; PersonMemberFunctionPointer pp; pp = &Person::sayHello; (someone .* pp)(); //等价于 (&someone ->* pp)(); //也等价于 someone.sayHello(); (xiaoming.*pp)(); //pp=&Child::sayHello;(不能运行,需要强制转换) ChildMemberFunctionPointer cp = &Child::sayHello; (xiaoming.*cp)(); runfuncName(&xiaoming,pp); PersonMemberFunctionPointer pp2 = &Person::sayName; (someone.*pp2)(); (xiaoming.*pp2)();//必须是公开继承,才有权限 //pp2 = &Child::sayName;(不能运行,需要强制转换) return 0;}
程序输出:
Starting /home/pc/build-1-Desktop_Qt_5_8_0_GCC_64bit-Debug/1...你好 4197112 【作者注:someone.sayHello();数字为输出的地址】你好 4197112 【作者注:虽然是xiaoming,但同样调用的是someone.sayHello();数字为输出的地址】你好 4197348 【作者注:xiaoming.sayHello();数字为输出的地址】你好 4197112 【作者注:虽然是xiaoming,但同样调用的是someone.sayHello();数字为输出的地址】我没有名字 1 【作者注:someone.sayName();数字为输出的地址】我是小明 1 【作者注:xiaoming.sayName();数字为输出的地址】/home/pc/build-1-Desktop_Qt_5_8_0_GCC_64bit-Debug/1 exited with code 0
分析上面的代码,其中
typedef void (*FunctionPointer)();
是普通函数指针,typedef void (Person::*PersonMemberFunctionPointer)();
是成员函数指针- 函数
runfuncName
中如果不适用typedef,那么必须PersonMemberFunctionPointer func
这么定义,可是由于使用了typedef,只需要Person::*func
,而void (Person::*func)()
为参数形式调用时的用法。 - 函数
runfuncName
中看出,通过函数调用时要通过“对象(obj->* func)()”这么调用。成员函数指针之所以要通过对象调用是因为形参中默认多了this指针,也就是成员函数sayHello的形参中 - 因为sayHello不是虚函数,所以
(xiaoming.*pp)();
是调用的Person类而不是Child类的sayHello。而runfuncName(&xiaoming,pp);
也是因为sayHello不是虚函数,故调用的仍是Person类。
②成员变量指针
看一段代码
#include <iostream>using namespace std;class A{ public: int x;};void func(A obj, int A::* p){//MemberPointer p cout<<obj.*p<<endl;}void func2(A * obj, int A::* p){ cout<<obj->*p<<endl;}template <class T>void func3(T * obj, int T::* p){ cout<<obj->*p<<endl;}typedef int A::* MemberPointer;int main(int argc, char *argv[]){ MemberPointer pV; //成员变量指针的定义 //等价于int A::* pV; pV = &A::x ; A a; a .* pV=1;//等价于a.x=1; cout << &a ->* pV << endl; func(a,pV); func2(&a,pV); func3(&a,pV); return 0;}
程序输出:
Starting /home/pc/build-2-Desktop_Qt_5_8_0_GCC_64bit-Debug/2...1 【作者注:a.x=1】1 【作者注:a.x=1】1 【作者注:a.x=1】1 【作者注:a.x=1】/home/pc/build-2-Desktop_Qt_5_8_0_GCC_64bit-Debug/2 exited with code 0
分析上面的代码,其中
void func(A obj, int A::* p)
是成员变量指针普通调用法,看详细定义:cout<<obj.*p<<endl;
看到‘.’了吧void func2(A * obj, int A::* p)
是指针调用法,看详细定义:cout<<obj->*p<<endl;
看到‘->’了吧template <class T>
是模板调用法,非本次讨论重点typedef int A::* MemberPointer;
定义类型名(将定义的变量名改为类型名)pV = &A::x ;
没有默认传this指针,这个pV为任何A类对象从这个对象首地址到这个成员变量x的偏移量
③函数指针
看一段代码
#include <iostream>using namespace std;void hello(){ cout<<"abc"<<endl;}int abc(int x){ return x+1;}typedef void (*pHello)();int main(int argc, char *argv[]){ //1 int (*fAbc)(int);//int (*fAbc)(int axc); fAbc=&abc; cout<<(*fAbc)(1)<<endl; //2 typedef int (*pF)(int);//should be with that pHello line above, but for the sake or understanding, put it here. pF y; y=&abc; //pF y=&abc; is also ok cout<<(*y)(1)<<endl; //3 void (*pf)(void); pf = &hello; (*pf)(); /*pf=hello pf()*/is also ok //4 pHello p = &hello; (*p)(); return 0;}
程序输出:
Starting /home/pc/build-3-Desktop_Qt_5_8_0_GCC_64bit-Debug/3...22abcabc/home/pc/build-3-Desktop_Qt_5_8_0_GCC_64bit-Debug/3 exited with code 0
分析上面的代码,其中
- //1中对于函数指针的声明为
int (*fAbc)(int);
,后面括号中的int也可以写成int xxx,即int (*fAbc)(int axc);
- //1中定义了一个指针变量fAbc,它是一个指向某种函数的指针,这种函数参数是一个int型,返回值是int类型。
- //1中对应的赋值方式为
fAbc=&abc;
- //1中对应的的调用方式为
(*fAbc)(1);
- //2中对于函数指针的声明为
typedef int (*pF)(int);
虽然与//1很相似,但//2的优点是更加直观方便 - //2中定义了一种pF的类型,并定义这种类型为指向某种函数的指针,这种函数以一个int为参数并返回int类型
- //2中对应的赋值方式为
pF y=&abc;
- //中对应的调用方式为
(*y)(1)
- //3和//4都大同小异
visitor tracker
0 0
- Qt_log2000_信号与槽中的connect函数之深入part1
- Qt_log2000_信号与槽中的connect函数之深入part2
- Qt_log2000_父子窗体传递数据-使用信号与槽
- qt中的connect()函数 信号槽
- QT 信号与槽 connect函数
- 信号与槽的connect连接函数
- 信号与槽,connect
- Qt中connect函数(信号与槽)初识
- QT中的信号-槽函数与多线程
- QT中Connect函数 信号槽
- QT信号与槽之槽函数
- Qt信号与槽之connectSlotsByName函数
- 深入了解信号与槽
- Qt中的信号和槽之connect----多线程调用全解析(同步/异步)
- Qt中的信号和槽之connect----多线程调用全解析(同步/异步)
- 深入探究connect函数
- 深入探究connect函数
- 深入探究connect函数
- SpringMVC视图知识点讲解
- 面试题3:二维数组中的查找
- 欢迎使用CSDN-markdown编辑器
- SpringMVC-1,helloworld
- 如鹏java学习进程 10s倒计时
- Qt_log2000_信号与槽中的connect函数之深入part1
- poj 1125 Stockbroker(多源最短路径)
- Python一
- 摄像机标定学习笔记(1)
- List集合的特有功能概述和测试
- php的几个面试题
- What
- 编程练习:矩阵类
- 实训2/6 Python 判断、循环、随机数……