标题:关于静态成员函数中调用非静态成员函数问题
只看楼主
鸿蒙之灵
Rank: 4
来 自:异次元裂缝
等 级:贵宾
威 望:11
帖 子:126
专家分:244
注 册:2016-8-22
结帖率:66.67%
 问题点数:0 回复次数:2 
关于静态成员函数中调用非静态成员函数问题
问题原型:

我总共两个类:CIPCOM\CView

CView类中有类数组 :CArray<CComIP, CComIP&> IPArray;

CIPCOM类中有静态成员函数:static UINT ReceiveUDP(LPVOID p);
      有非静态成员函数:unsigned int getIPType();

因为CIPCOM类中的静态成员函数ReceiveUDP(LPVOID p)需要启动UDP通信线程,所以形参不能随意变动,无法将确切的实例通过参数传递进来,而该静态函数中又需要调用非静态成员函数getIPType(),此时需要如何获取活动的实例?


代码结构
程序代码:
//CView类
for(int i=0;i<IPArray.GetSize();i++)
{
    IPArray.IP_Init();
}

//CIPCOM类
void CIPCOM::IP_Init()
{
    //创建套接字部分
    //绑定套接字部分

    //启动数据接收线程
    AfxBeginThread(ReceiveUDP, this, THREAD_PRIORITY_NORMAL, 0, 0, NULL);
}
UINT CIPCOM::ReceiveUDP()
{
    if (JSJ_COM == getIPType())   //JSJ_COM-为宏定义----此处调用非静态成员函数,是我的疑惑之处:我要怎么能够获取到当前所活动的类实例
    {
        //数据接收解析逻辑
    }
}
unsigned int CIPCOM::getIPType()   //按照软件功能及相关设计,此处我不愿意定义为静态成员
{
    return IP_TYPE;
}


[此贴子已经被作者于2020-2-28 20:51编辑过]

搜索更多相关主题的帖子: int int 函数 函数 调用 成员 成员 静态 静态 调用 
2020-02-28 20:34
鸿蒙之灵
Rank: 4
来 自:异次元裂缝
等 级:贵宾
威 望:11
帖 子:126
专家分:244
注 册:2016-8-22
得分:0 
该问题已解决:

解决方案:将该线程提出来,放在CView类中,套接字的创建和绑定继续放在CIPCOM类中;

在CView类的初始化中遍历IPArray数组,然后用数组元素去调用创建和绑定套接字函数,依据所有数组元素创建和绑定套接字函数的返回值,如果所有的UDP通道都绑定成功,再启动线程,该线程中处理所有IPArray的UDP通道数据,所以在绑定套接字时,需要以非阻塞方式绑定(否则会出现线程启动后,当遇到某一个通道未从指定通道中取到有效数据时,后续通道数据就不处理的情况);

绑定非阻塞式UDP通道方法如下:
程序代码:
sockSrv = socket(AF_INET,SOCK_DGRAM,0);  //创建服务器套接字
if(sockSrv == INVALID_SOCKET)
{
    //提示创建失败
    WSACleanup();
    return FALSE;
}
addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");  //此处指定本地IP地址
addrSrv.sin_family = AF_INET;
addrSrv.sin_port = htons(8800);    //此处指定本地UDP端口

addrClient.sin_addr.s_addr = inet_addr("127.0.0.1");   //此处指定目的IP地址
addrClient.sin_family = AF_INET;
addrClient.sin_port = htons(9900);    //此处指定目的UDP端口

unsigned long iMode=1;   //0-阻塞式绑定,  非0-非阻塞式绑定
::ioctlsocket(sockSrv,FIONBIO,&iMode);

int nRet=bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));  //绑定socker参数
if(nRet == SOCKET_ERROR)
{
    //提示绑定失败
    WSACleanup();
    return FALSE;
}


在绑定套接字之前,需启动UDP通信Winsocker
    WSADATA wsaData;
    WSAStartup(MAKEWORD(2, 2), &wsaData);  //启动Winsocket----此处在整个解决方案中只需要执行一次


此处为何在CIPCOM类中的静态函数中不能访问非静态成员函数:
static成员函数属于类,独立于对象存在,不依赖于对象。随着类的加载而加载,优先于对象存在,被所有对象共享,可以直接被类名调用。

调用方式:
类名::成员名
对象名.成员名

static成员函数中没有this指针,非static成员函数中拥有this指针。
对象与对象之间的成员变量是相互独立的。要想共用数据,则需要使用静态成员和静态方法
静态成员变量虽然在类中,但它并不是随对象的建立而分配空间的,也不是随对象的撤销而释放(一般的成员在对象建立时会分配空间,在对象撤销时会释放)。静态成员变量是在程序编译时分配空间,而在程序结束时释放空间。
普通成员函数和静态成员函数的区别是:普通成员函数在参数传递时编译器会隐藏地传递一个this指针.通过this指针来确定调用类产生的哪个对象;但是静态成员函数没有this指针,不知道应该访问哪个对象中的数据,所以在程序中不可以用静态成员函数访问类中的普通变量.

对待编程,要像对待情人一样
2020-03-01 00:44
return_0
Rank: 8Rank: 8
来 自:五维空间
等 级:禁止访问
威 望:3
帖 子:512
专家分:838
注 册:2020-1-28
得分:0 
厉害了

2020-03-05 16:52



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-499462-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.022038 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved