-
2020-05-02 14:28:37
首先先搞明白 声明、定义、初始化
类的静态成员变量在类内声明,可以多次声明类的静态成员必须在类外定义,定义就是给变量分配内存,
初始化就是给一个变量赋初值,内置类型通常定义时默认初始化
类静态成员变量在main函数执行前完成初始化,有静态初始化和动态初始化
static initialization: 静态初始化指的是用常量来对变量进行初始化,主要包括 zero initialization 和 const initialization,静态初始化在程序加载的过程中完成,对简单类型(内建类型,POD等)来说,从具体实现上看,zero initialization 的变量会被保存在 bss 段,const initialization 的变量则放在 data 段内,程序加载即可完成初始化,这和 c 语言里的全局变量初始化基本是一致的。
dynamic initialization:动态初始化主要是指需要经过函数调用才能完成的初始化,比如说:int a = foo(),或者是复杂类型(类)的初始化(需要调用构造函数)等。这些变量的初始化会在 main 函数执行前由运行时调用相应的代码从而得以进行(函数内的 static 变量除外)。更多相关内容 -
Java静态和非静态成员变量初始化过程解析
2020-08-25 04:07:54主要介绍了Java静态和非静态成员变量初始化过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 -
C++静态成员变量初始化
2021-06-17 10:35:00静态成员变量初始化 静态成员变量可以初始化,但只能在类体外进行初始化。如: long long student::number = 13926572996; //在类体外对静态成员变量赋值 其一般形式为: 数据类型 类名::静态成员变量名 = ...静态成员变量初始化
静态成员变量可以初始化,但只能在类体外进行初始化。如:
long long student::number = 13926572996; //在类体外对静态成员变量赋值
其一般形式为:
数据类型 类名::静态成员变量名 = 初值;
不必在初始化赋值语句中加 static。
注意:不可以在构造函数的参数初始化表中对静态成员变量初始化,例如:
student(char* pn, char* pa, int n):number(n)
{
strcpy(name, pn);
strcpy(addr, pa);
}
在构造函数中,对static类型的number成员进行初始化,是错误的操作。
如果未对静态成员变量赋值,则编译系统会自动赋初值为0。
如果一个成员变量定义为const类型,同时,也是static类型,那么,应该怎么样初始化?有如下的分析:
(1) static类型的成员变量,需要在类外进行初始化;
(2) const类型的成员变量,需要在构造函数的初始化列表进行初始化;
那么,const类型的static成员变量,不可以在构造函数的初始化列表中进行初始化,例如:
程序编译错误,如下:
提示 student::number成员变量是static类型,仅仅在定义的时候可以初始化。所以,不可以在构造函数列表中初始化。所以,在类外对static类型的成员变量进行初始化,程序测试代码如下:
程序运行结果如下:
所以,可以在类外对const类型的静态成员变量进行初始化。
注意:对于const 类型的static成员变量,可以在定义它的时候进行初始化,如下:
在student类内对number成员进行初始化。这是合法的语句。
韦凯峰 Linux C/C++ 程序设计教程,Linux 系统编程,Openwrt 系统开发,微信:13926572996,QQ:1523520001,博客:www.mylinux.vip
-
Java中static静态变量的初始化完全解析
2020-09-02 04:24:44static所声明的变量在Java中有一个初始化的先后顺序,带着这个问题接下来我们就来进行Java中static静态变量的初始化完全解析: -
C++类的静态成员初始化详细讲解
2020-09-05 00:10:09通常静态数据成员在类声明中声明,在包含类方法的文件中初始化.初始化时使用作用域操作符来指出静态成员所属的类.但如果静态成员是整型或是枚举型const,则可以在类声明中初始化 -
类的静态成员变量初始化问题
2019-08-12 20:24:37我们都知道类的静态成员变量必须在类外初始化,不仅如此,类的静态成员变量最好在源文件中初始化,而不能在头文件初始化,否则,编译的时候就会报错"symbol multiply defined". 举例: /*--testA.h--*/ class A ...我们都知道类的静态成员变量必须在类外初始化,不仅如此,类的静态成员变量最好在源文件中初始化,而不能在头文件初始化,否则,编译的时候就会报错"symbol multiply defined".
举例:/*--testA.h--*/ class A { public: void testB(); private: struct B { int getStatic(); void addStatic(); static int seq; //static member variable int num; }; //int A::B::seq = 0; //error, must be defined in cpp file }; //int A::B::seq = 0; //error, must be defined in cpp file
#include "test30-static-member.h" void A::testB() { B b[2]; b[0].addStatic(); std::cout << b[0].getStatic() << std::endl; b[1].addStatic(); std::cout << b[1].getStatic() << std::endl; } int A::B::seq = 0; //right
/*--main.cpp--*/ #include "testA.h" //int A::B::seq = 0; //also work int main() { A a; a.testB(); return 0; }
输出:
1
2C++中有声明(declare)和定义(define)的概念,
int A::B::seq = 0;
与其叫做初始化,叫做定义更准确, 而结构体中的这句话实际为声明。
C++中的所有变量、函数、类等都只能定义一次,可以声明多次。 如果把int A::B::seq = 0;
放到头文件中,头文件被多次include, 则可能会导致变量被多次声明, 因此不可行。??
declare: 编译期告诉编译器变量的名字和类型
define: 链接的时候告诉变量存放位置,函数实体等。
??根据评论提醒,static const的成员变量可以在类内初始化, 但仅限于整型和enum型。
总结:
In C++11, non-static data members, static constexpr data members, and static const data members of integral or enumeration type may be initialized in the class declaration.
struct X { int i=5; // ok const float f=3.12f; // ok static const int j=42; // ok static constexpr float g=9.5f; //ok static const double d = 1.23; // error static const char* cstr = "FOO"; // error struct FooT { int i; }; static const FooT foo; // ok };
https://stackoverflow.com/questions/9141950/initializing-const-member-within-class-declaration-in-c
https://stackoverflow.com/questions/19575258/why-must-non-integral-static-data-members-initialized-in-the-class-be-constexprOne of the reasons why this was the case prior to C++11’s addition of constexpr was the standard did not specify how floating points were to be implemented (it is left to the processor/architecture - for example, when you say float x = 1.6f, it is actually 1.6000000000024 on most systems).
-
C++静态成员变量初始化和赋值
2019-03-07 14:29:57这里说一下C++静态成员变量,在C++中,静态成员是属于整个类的而不是某个对象,静态成员变量只存储一份供所有对象共用。所以在所有对象中都可以共享它。使用静态成员变量实现多个对象之间的数据共享不会破坏隐藏的...1.背景
有这样一套会话机制,CSession为会话对象,CSessionManager为会话管理类,在CSession会话需要销毁时,CSession主动发送消息给CSessionManager销毁session。同时CSession是一个基类,子类通过继承CSession实现不同的session处理。
实现主要考虑三个方面(创建、处理、销毁):
- 通过不同的server创建不同的session会话;
- 子类通过CSession提供的虚函数接口实现多态;
- 通过消息对象指针发送消息给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为消息队列模板类 }
分析-有用信息:
- 在如上代码中,m_exception_msq只是声明,并没有定义和初始化。
- “undefined reference to”是未定义……;
- 项目中有地方使用静态变量的地方都在.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++静态成员变量:
- 必须在外部定义和赋值;
- 不能在 main() 函数中定义
- 不能在类的构造函数中定义
- 必须要定义静态变量,否则该变量没有内存空间(类中只是申明) ;
- 类本身可以直接调用静态变量
- 静态变量依旧符合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/47067549
https://blog.csdn.net/buknow/article/details/80275191 -
Java构造方法、成员变量初始化以及静态成员变量初始化三者的先后顺序是什么样的?
2018-09-28 17:46:06【Java笔试真题】:构造方法、成员变量初始化以及静态成员变量初始化三者的先后顺序是什么样的? 【解答】: 当类第一次被加载的时候,静态变量会首先初始化,接着编译器会把实例变量初始化为默认值,然后执行构造方法... -
关于Java静态成员变量和静态初始化块等的初始化顺序的详细介绍
2013-09-23 16:41:25详细介绍了Java的静态成员变量、静态数据块、非静态成员变量和非静态成员变量等初始化顺序 -
Java变量的初始化及静态方法的实现
2020-08-25 12:53:22主要介绍了Java变量的初始化及静态方法的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 -
全局变量,局部静态变量初始化以及类静态成员变量初始化
2016-07-05 11:32:54全局变量、文件域的静态变量和类的静态成员变量在main执行之前的静态初始化过程中分配内存并初始化;局部静态变量(一般为函数内的静态变量)在第一次使用时分配内存并初始化。这里的变量包含内置数据类型和自定义... -
c++静态成员变量的初始化
2021-10-20 17:13:40普通静态变量的初始化 #include<iostream> using namespace std; ...静态成员变量的初始化 参考以下文章 c++静态成员变量的初始化 #include<iostream> using namespace std; class A { -
C++中类成员变量初始化总结
2021-01-21 17:09:38考虑一下效率的可以再构造函数的初始化列表中进行。 class CA { public: int data; …… public: CA(); …… }; CA::CA():data(0)//……#1……初始化列表方式 { //data = 0;//... -
php 静态变量的初始化
2020-10-29 14:23:20php的成员变量可以在声明的同时进行初始化,但是只能用标量进行初始化。 -
Java中非静态成员变量、静态成员变量的初始化时机。
2018-05-22 11:48:11Java中非静态成员变量、静态成员变量的...成员变量初始化语句; 成员变量初始化块; 构造函数; 示例一: public class MyTest { private String name = "wei.hu"; public MyTest(String name) { ... -
C++中如何初始化静态成员变量
2018-11-26 20:04:11例子,比如我们有一个People类,其中包含一个private的静态成员变量num class People{ private: static int num; public: void show(){ cout<<num<<"\n"; } } 静态... -
静态成员变量的初始化
2017-03-16 16:43:00我们定义如下类: 复制代码 //A.h class A ...其中包含三个私有的静态类成员,C++规定const静态类成员可以直接初始化,其他非const的静态类成员需要在类声明以外初始化,我们一般选择在类的实 -
C++静态成员变量的初始化
2018-06-19 07:52:28class example{ public: //static double rate=6.5; static const int size; std::vector<double> vec(size); }; 代码是这样的。当时我一看,觉得没有错误啊。...size这个变量不是co... -
C++中静态初始化数组与动态初始化数组详解
2020-12-26 08:04:37静态初始化的数组的长度必须是在程序中确定的常数,不能是由用户输入的变量 例子: int a[10];//正确 Student stud[10];//正确:Student是一个学生类 int n;cin>>n;int a[n];//错误 int n;cin>>n;Student stud[n];/... -
Java静态变量和成员变量初始化顺序
2018-08-01 19:22:49首先放一段代码,帮助我们分析变量初始化过程,大家可以先想一下他的输出,然后在看下面的运行结果: public class InitTest{ public static int k = 0; public static InitTest t1 = new InitTest("t1"... -
静态变量和成员变量的初始化时机
2018-12-22 09:42:59静态变量和成员变量的初始化时机 `静态变量:` 在class类首次被加载的时候进行初始化 `成员变量:` 在new对象的时候被初始化 -
C++静态成员变量的定义与初始化注意事项
2019-08-19 20:31:07而对于类的静态成员来说,同样是所有类共享一个静态成员,需要注意的是静态成员的初始化 如下面代码 class A { public: static int a; // static int a = 1; // ERROR }; int A::a = 1; int main() { cout &l... -
c++类static成员变量初始化
2019-05-10 23:12:38今天看到一个写法,竟然不知道这种写法。。。我是不是脑子完犊子了。。。 在test.h文件中: class A { public: ... //静态数据成员的定义和初始化 ...类中的静态成员变量的初始化必须在类外实现!! ... -
c++中的静态成员变量如何初始化
2018-04-07 14:01:10class A { static int a ; } 在A.cpp文件中这样初始化才可以 int A:: a = 3; -
C++类的静态成员变量一定要初始化(分配内存)
2018-07-11 09:06:29其实这句话“静态成员变量是需要初始化的”是有一定问题的,应该说“静态成员变量需要定义”才是准确的,而不是初始化。两者的区别在于:初始化是赋一个初始值,而定义是分配内存。静态成员变量在类中仅仅是声明,... -
java静态成员变量的初始化
2014-08-21 21:33:57看过Thinking in java的人都知道,在不考虑父类的情况下,类的初始化顺序相对简单,总体是先静态的,然后是非静态的。这里都包括成员变量和代码块。对于静态变量和静态代码块,不管它们在何处定义,总是按照其先后... -
Java中成员变量的初始化过程
2021-03-09 17:45:24Java中的成员变量分为两种:第一种是成员变量,第二种是...1.没有被修饰符修饰的成员变量和局部变量的初始化在java中所有的成员变量都会被系统赋予默认是初始值,这个初始值根据不同的数据类型有着不同的定义:Bool... -
java 静态成员三种初始化方法
2019-09-26 17:02:34声明的时候初始化 在 static block中初始化 class Demo { public static int z; ... //初始化代码 ... 写一个私有静态方法去初始化 class name { public static varType myVar = initi...