C++静态成员变量初始化和赋值

C++静态成员变量初始化和赋值1 背景有这样一套会话机制 CSession 为会话对象 CSessionMana 为会话管理类 在 CSession 会话需要销毁时 CSession 主动发送消息给 CSessionMana 销毁 session 同时 CSession 是一个基类 子类通过继承 CSession 实现不同的 session 处理 实现主要考虑三个方面 创建 处理 销毁 通过不同的 server 创建不同的 session

1.背景

有这样一套会话机制,CSession为会话对象,CSessionManager为会话管理类,在CSession会话需要销毁时,CSession主动发送消息给CSessionManager销毁session。同时CSession是一个基类,子类通过继承CSession实现不同的session处理。

实现主要考虑三个方面(创建、处理、销毁):

  1. 通过不同的server创建不同的session会话;
  2. 子类通过CSession提供的虚函数接口实现多态;
  3. 通过消息对象指针发送消息给CSessionManager销毁session;

问题卡在session的销毁:

CSessionManager通过消息队列模板类创建消息对象,保存消息对象指针信息,并且有一个线程专门接收该对象发送的消息。那么CSession会话类也需要知道和保存消息对象指针。

先前有类似情况,消息对象指针是通过构造传参保存下来的。但现在CSession作为一个基类(要被继承),显然通过构造传参是非常不合理的,并且我希望CSession只保存一份消息对象指针(static成员变量),提供唯一 一个发送消息的接口给子类。

大致代码如下:

typedef struct { 
    int connfd; int keepfd; /*是否保留fd:1-是,其他-否*/ }SocketSessionExp; //session会话基类(HttpSession、RtspSession继承该类) class CSession { 
    friend class CSessionManager; public: CSession(); virtual ~CSession(); protected: static void sendMessage(SocketSessionExp &expMessage);//希望CSession对象和子类能通过这个唯一接口发送消息给CSessionManager销毁该CSession会话 private: static TMessageQue<SocketSessionExp> *m_exception_msq;//TMessageQue为消息队列模板类 } //会话管理类 class CSessionManager { 
    public: static CSessionManager* instance(); //单健类 private: CSessionManager(); { 
    m_exception_msq = new TMessageQue<SocketSessionExp>(); CSession::m_exception_msq=m_exception_msq; } ~CSessionManager();//不是重点未给出 private: static TMessageQue<SocketSessionExp> *m_exception_msq;//在构造函数中new一个类对象 std::map<int,CSession*> m_sessionMap; } 

该模块编译时没报错,链接时报错提示:

undefined reference to `Network::CSession::m_exception_msq' 

2.试错

CSessionManager是CSession的友元类,可直接访问CSession的私有成员和保护成员。也尝试通过函数、局部CSession等方式来完成m_exception_msq的赋值,均报错。

3.分析与百度

class CSession { 
    friend class CSessionManager; public: CSession(); virtual ~CSession(); private: static TMessageQue<SocketSessionExp> *m_exception_msq;//TMessageQue为消息队列模板类 } 

分析-有用信息:

  1. 在如上代码中,m_exception_msq只是声明,并没有定义和初始化。
  2. “undefined reference to”是未定义……;
  3. 项目中有地方使用静态变量的地方都在.cpp文件上方进行了初始化(实际是定义–>初始化)。

分析推测:应该是m_exception_msq未定义。

在.cpp文件中添加如下代码:

//xxx.cpp TMessageQue<SocketSessionExp>* CSession::m_exception_msq=NULL; 

编译成功、链接成功、通过打印信息也看到CSession::m_exception_msq在CSessionManager构造中完成了赋值,问题解决了。

这里一方面是对static成员变量的理解不到位,另一方面是分析的时候没有抓住有效信息浪费了不少时间。(“undefined reference to”)

4.C++静态成员变量

C++的变量的类型大致有普通成员变量、静态成员变量、成员常量这三种,还有一种组合的静态成员常量。

这里说一下C++静态成员变量,在C++中,静态成员是属于整个类的而不是某个对象,静态成员变量只存储一份供所有对象共用。所以在所有对象中都可以共享它。使用静态成员变量实现多个对象之间的数据共享不会破坏隐藏的原则,保证了安全性还可以节省内存。

static成员的所有者是类本身和对象,但是多个对象拥有一样的静态成员。从而在定义对象时不能通过构造函数对其进行初始化; 静态成员不能在类定义里边初始化,只能在class body外初始化; 静态变量依旧符合public、private、protect特性; 静态成员函数没有this指针,它不能返回非静态成员,因为除了对象会调用它外,类本身也可以调用 。

C++静态成员变量:

  1. 必须在外部定义和赋值;
    • 不能在 main() 函数中定义
    • 不能在类的构造函数中定义
  2. 必须要定义静态变量,否则该变量没有内存空间(类中只是申明) ;
  3. 类本身可以直接调用静态变量
  4. 静态变量依旧符合public、private、protect特性

C++成员变量声明、初始化、赋值说明列表:

数据成员类型 normal const static static const
类内直接初始化(在声明时就赋值) ×
先声明再通过初始化列表赋初值 × ×
先声明再在构造函数体里赋初值 × × ×
先声明再在类外赋初值 × ×

5.C++静态成员方法

1、静态方法可以被类直接调用,但是同静态变量一样符合public、private、protect特性

2、静态成员函数不可以调用类的非静态成员。因为静态成员函数不含this指针。

3、静态成员函数不可以同时声明为 virtual或后缀const 函数。因为virtual就是用来区分是哪个对象调用了他,与静态方法矛盾。而后缀const是用来修饰this指针的,静态变量中不包含this指针。

参考资料:
https://blog.csdn.net/nwd0729/article/details/
https://blog.csdn.net/buknow/article/details/

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/232884.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 遗传算法优化bp神经网络matlab代码_神经网络进化算法

    遗传算法优化bp神经网络matlab代码_神经网络进化算法最近在学遗传算法优化BP神经网络,从新浪博客,Matlab中文论坛以及《MATLAB神经网络43个案例分析》里看了许多资料,存在着缺少test函数,以及函数名调用错误等问题。自编了test函数,调整后,供大家参考,(在Matlab2006a亲测可行)。参考文献:《MATLAB神经网络的43个案例分析》王小川,史峰,郁磊等,北京航空航天大学出版社。flyingnosky的sina博…

    2025年10月27日
    3
  • noip宝藏_寻宝官方网

    noip宝藏_寻宝官方网看到这道题,我就想到了直接根据行走路径进行操作,结果——一片WA,悲伤,那么除了这样,怎么解决呢?我们用到的方法是用数组存储每层楼有向上楼梯的个数,以及每个房间的情况,然后将要走的次数模上总个数,再用得到的值加上最初的房间,即可。下面是代码:#include&lt;bits/stdc++.h&gt;usingnamespacestd;constintN=100…

    2022年8月22日
    8
  • Longest Common Prefix_LeetCode

    Longest Common Prefix_LeetCode1.思路:求strs数组的长度,当len==0,len==1分开考虑;i从1-min_len,以strs[0][i]作为对照,一旦出现strs[j][i]!=strs[0][i],结束循环,则输出之前判断好了的字符串。 classSolution:deflongestCommonPrefix(self,strs):""":typestrs…

    2022年5月6日
    45
  • 免费sun.misc.BASE64Decoder.jar下载「建议收藏」

    免费sun.misc.BASE64Decoder.jar下载「建议收藏」相信很多人在转base64时,需要BASE64Decoder包,然而网上都需要C币或者某豆,本着开源思想,资源共享原则,分享链接如下,大家可以自行下载:https://pan.baidu.com/s/127YeW2y_j1NNyrE3w70Ztg,此链接永久有效!!!如有疑问,请联系zhang_quan_888@163.com….

    2022年7月16日
    16
  • a 标签去掉下划线[通俗易懂]

    a 标签去掉下划线[通俗易懂]text-decoration:none

    2022年5月2日
    38
  • 近期的一些研究目标

    近期的一些研究目标

    2021年8月18日
    43

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号