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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 用python3实现粒子群优化算法(PSO)

    用python3实现粒子群优化算法(PSO)粒子群优化算法(ParticleSwarmOptimization,PSO)属于进化算法的一种,是通过模拟鸟群捕食行为设计的。从随机解出发,通过迭代寻找最优解,通过适应度来评价解的品质。设想这样一个场景:一群鸟在随机搜索食物。在这个区域里只有一块食物。所有的鸟都不知道食物在那里。但是他们知道当前的位置离食物还有多远。那么找到食物的最优策略是什么呢。最简单有效的就是搜寻目前离食物最近的鸟的周围区…

    2022年5月24日
    43
  • linux goland21.2.4激活【最新永久激活】

    (linux goland21.2.4激活)JetBrains旗下有多款编译器工具(如:IntelliJ、WebStorm、PyCharm等)在各编程领域几乎都占据了垄断地位。建立在开源IntelliJ平台之上,过去15年以来,JetBrains一直在不断发展和完善这个平台。这个平台可以针对您的开发工作流进行微调并且能够提供…

    2022年3月30日
    311
  • python安装教程[通俗易懂]

    python安装教程[通俗易懂]python安装教程本章节我们将向大家介绍如何在本地搭建Python开发环境。Python可应用于多平台包括Linux和MacOSX。你可以通过终端窗口输入"python&

    2022年7月5日
    24
  • 详解Java中的clone方法

    详解Java中的clone方法

    2022年3月1日
    46
  • eclipse500错误原因解决方法_eclipse运行无法显示网页

    eclipse500错误原因解决方法_eclipse运行无法显示网页eclipse内部浏览器报错:此错误(HTTP500内部服务器错误)意味着您正在访问的网站出现了服务器问题,此问题阻止了该网页的显示修改eclipse设置即可解决:window-&gt;preferences-&gt;general-&gt;webbrowser选择使用外部浏览器即可IE浏览器设置如下:https://blog.csdn.net/txwtech/article/details…

    2022年8月11日
    9
  • IOS系列——NStimer[通俗易懂]

    IOS系列——NStimer

    2022年1月28日
    39

发表回复

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

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