大家都知道C++中类的成员函数默认都提供了this指针,在非静态成员函数中当你调用函数的时候,编译器都会“自动”帮你把这个this指针加到函数形参里去。当然在C++灵活性下面,类还具备了静态成员和静态函数,即
-
2020-02-04 13:00:38
C++中的静态成员包括静态数据成员和静态成员函数。
静态数据成员
一、介绍及作用
在一个类中,如果在一个数据成员前冠以关键字
static
,那么这种数据成员就叫做静态数据成员。与一般的数据成员不同,无论建立多少个类的对象,都只有一份静态数据成员的拷贝,也就是说,静态数据成员为该类的所有对象所共享。
C++支持静态数据成员的一个主要原因就是可以不必使用全局变量,因为全局变量破坏了C++封装的特点。静态数据成员的主要用途就是定义类的所有对象的公有数据,如平均数、总数等。二、定义
格式如下:
static 数据类型 数据成员名称
列如:
static int age;
这样便定义了一个静态数据成员。
三、初始化
格式如下:
数据类型 类名::静态数据成员名=初始值
例如:
int Student :: age=10;
如果在初始化时,没有对其赋初值,那么编译器就会自动为其赋初值0。例如:
int Student :: age;
等价于
int Student :: age=0;
注意:静态数据成员的初始化必须在类外且在创建对象之前进行初始化。
四、 访问方式
(1)类名::静态数据成员名 (2)对象名.静态数据成员 (3)对象指针->静态数据成员
静态成员函数
一、介绍及作用
在普通的函数前面冠以关键字
static
,就是静态成员函数。静态成员函数属于整个类,静态成员函数的作用就是处理静态数据成员。二、定义
格式如下:
static 返回类型 函数名称(参数表)
例如:
static int fun1(int x,int y);
三、调用方式
(1)类名::静态成员函数名 (2)对象名.静态成员函数名 (3)对象指针->静态成员函数名
四、附加小知识
(1)静态成员函数与非静态成员函数的区别:非静态成员函数有this指针,而静态成员函数没有this指针。
(2)静态成员函数可以直接访问本类中的静态数据成员,也可以通过对象名或对象指针或对象引用来间接访问非静态数据成员。
(3)静态成员函数与静态数据成员一起使用,达到了同一个类中不同对象之间数据共享的目的。
(4)可以在建立任何对象之前调用静态成员函数或者访问静态数据成员。更多相关内容 -
详解c++ 静态成员变量
2020-12-17 00:17:53仔细琢磨静态成员变量,会发现其与C++的方式既相容也矛盾,具有特殊性。 先说相容的一面。·C/C++·有声明和定义的说法:声明给出签名,定义给出具体实现。对类型而言,声明不一定能知道其对象占用空间大小,但根据... -
C++静态成员变量和静态成员函数的使用方法总结
2020-12-26 00:59:12静态成员变量: 类体中的数据成员的声明前加上static关键字,该数据成员就成为了该类的静态数据成员。和其他数据成员一样,静态数据成员也遵守public/protected/private访问规则。同时,静态数据成员还具有以下特点... -
C++静态成员函数访问非静态成员的几种方法
2020-12-22 16:23:45大家都知道C++中类的成员函数默认都提供了this指针,在非静态成员函数中当你调用函数的时候,编译器都会“自动”帮你把这个this指针加到函数形参里去。当然在C++灵活性下面,类还具备了静态成员和静态函数,即 ... -
关于C++静态成员函数访问非静态成员变量的问题
2020-09-04 23:55:15静态成员函数不能访问非静态成员,这是因为静态函数属于类而不是属于整个对象,静态函数中的 member可能都没有分配内存。静态成员函数没有隐含的this自变量。所以,它就无法访问自己类的非静态成员 -
C++静态成员函数不能调用非静态成员变量(详解)
2020-08-31 21:43:00下面小编就为大家带来一篇C++静态成员函数不能调用非静态成员变量(详解)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧 -
c++静态成员使用实例
2019-04-16 16:20:15c++静态成员使用实例,是在学习谭浩强老师c++课本的过程中写的 -
c++类中的静态成员和非静态成员
2021-01-20 03:36:42首先呢我们知道c++类中的成员分为成员变量和成员函数两大类,如果再加上static给以区分的话那么会有以下四种:静态成员变量,非静态成员变量;静态成员函数,非静态成员函数 (1)成员变量 我们知道类的静态成员... -
C++ 静态成员的类内初始化详解及实例代码
2020-12-26 10:37:17C++ 静态成员的类内初始化详解及实例代码 一般来说,关于C++类静态成员的初始化,并不会让人感到难以理解,但是提到C++ 静态成员的”类内初始化”那就容易迷糊了。 我们来看如下代码: //example.h #include #... -
C++静态成员变量和静态成员函数
2021-01-21 16:43:10静态成员变量和静态成员函数 class ClassA { int a; int b; static int c; //静态成员变量 static void xxx_fun() //静态成员函数 { ... } } 普通成员变量每个对象都有各自的一份,静态成员变量所有对象... -
C++中静态成员函数与静态成员变量(static )
2021-01-20 05:54:09C++中静态成员函数与静态成员变量(static ) 这篇介绍了静态成员函数与静态成员变量,是我的读书笔记,我希望它够简短但又比较全面,起到复习的作用。如果有一些C++知识记不清楚了,它可以帮你很快回忆起来。 复习... -
C++类静态成员与类静态成员函数详解
2021-01-20 06:31:04当将类的某个数据成员声明为static时,该静态数据成员只能被定义一次,而且要被同类的所有对象共享。各个对象都拥有类中每一个普通数据成员的副本,但静态...静态成员不可在类体内进行赋值,因为它是被所有该类的对象所 -
C++中静态成员函数访问非静态成员的实例
2020-12-31 15:42:53C++中静态成员函数访问非静态成员的实例 实现代码: #include /* 静态成员函数只能访问静态数据成员、静态成员函数和类以外的函数和数据,不能访问非静态数据成员,但静态成员函数或静态数据成员可由任意访问许可... -
C++类的静态成员初始化详细讲解
2020-09-05 00:10:09通常静态数据成员在类声明中声明,在包含类方法的文件中初始化.初始化时使用作用域操作符来指出静态成员所属的类.但如果静态成员是整型或是枚举型const,则可以在类声明中初始化 -
C++ 中静态成员函数与非静态成员函数的区别
2020-08-30 14:52:34主要介绍了C++ 中静态成员函数与非静态成员函数的区别的相关资料,需要的朋友可以参考下 -
C++静态成员函数访问非静态成员的四种方法
2021-07-01 17:00:48大家都知道C++中类的成员函数默认都提供了this指针,在非静态成员函数中当你调用函数的时候,编译器都会“自动”帮你把这个this指针加到函数形参里去。当然在C++灵活性下面,类还具备了静态成员和静态函数,即 class...class A { public: static void test() { m_staticA += 1; } private: static int m_staticA; int m_a };
此时你的test函数只能去访问m_staticA成员,而不能去访问m_a。同学可能会问,这算什么问题?问题都是在应用场景中才能体现的,我一开始也是不以为意,直到我遇到了回调函数这个烦人的问题我才真正静下心来去考虑这个知识点。
先简单说下回调,在座的应该都知道回调的含义,在C中回调主要体现就是回调函数,当然C++中也有仿函数等其他用法,抛开这些,单纯在回调函数这个点上我们进行如下讨论。
由于C++类的成员函数都隐含了this指针,如果我直接注册,比如:
typedef void (A::*FunPtr)(); FunPtr p = A::hello; p();
此时程序会报错,提示信息是你缺少一个this指针,意味着你要真的想使用p,你必须有一个分配好空间的实例才能来调用
typedef void (A::*FunPtr)(); FunPtr p = A::hello; A a; A *pA = new A(); (a.*p)(); (pA->*p)();
当然,如果仅仅是对C++的类静态函数进行回调函数注册,你是不需要考虑this指针的
typedef void (A::*FunPtr)(); FunPtr p = A::test; p();
但问题就是,你此时的静态函数是不能拥有你的成员变量的,看到了吧,问题来了。面对这种需求,我们就真正应该静下心来好好想想,究竟如何才能让静态函数去访问非静态成员变量这个问题了。
有如下四种方法:
- ① 在静态函数的形参表里加上实例的地址;
- ② 在静态函数中使用全局变量;
- ③ 静态成员函数可以访问静态成员,在类是单例类的情况下,可以在创建的时候把
this
指针赋值给那个静态成员,然后在静态成员函数内部访问this
指向的静态成员; - ④ 在静态函数的形参比加上一个
void *
的内存首地址,然后在内部做转换;
具体示例如下:
方法一:
有一个很取巧的办法,就是在静态函数的形参表里加上实例的地址,也就是:
class A { public: static void test(A *a) { a->m_a += 1; } void hello() { } private: static int m_staticA; int m_a };
这样在你回调函数的时候,你可以通过这个来让本身不能访问成员非静态变量的静态函数(太拗口)来访问非静态成员变量。
方法二:
其实这个方法在GLIB中用的很多,就是在静态函数中使用全局变量,即:
A g_a; class A { public: static void test() { g_a.m_a += 1; } void hello() { } private: static int m_staticA; int m_a };
这种方法我们了解就好,全局变量我们并不推荐。
方法三:
静态成员函数不能访问非静态成员,但别忘了,静态成员函数可以访问静态成员,在类是单例类的情况下,可以在创建的时候把
this
指针赋值给那个静态成员,然后在静态成员函数内部访问this
指向的静态成员:class A { public: A() { m_gA = this; } static void test() { m_gA.m_a += 1; } void hello() { } private: static int m_staticA; static A *m_gA; int m_a };
方法四:
和方法一比较像,但他的方向思想更多的是针对内存块这个概念,意思就是在静态函数的形参比加上一个
void *
的内存首地址,然后在内部做转换:class A { public: static void test(void *pData) { A *a = static_cast<A*>(pData); a->m_a += 1; } void hello() { } private: static int m_staticA; int m_a }; A a; test(&a);
如上,我整理了4种方法,当然方法还有很多,其实绕了这么大远路,我们的希望就是不破坏回调函数整洁的函数接口(即不在回调函数形参列表中加上自己的实例指针)而做的妥协,如果你更喜欢通过改变接口或者通过用Java类似的interface方式来实现,那也没有问题,这里主要就是提供给大家一个思路,C++确实很灵活,我们要用好这把双刃剑 : )
-
C++静态成员变量的定义
2021-06-17 10:34:171静态成员 如果定义了一个student类,定义 3 个student类的对象,如下: student stud1, stud2, stud3; 那么,每一个student类对象都分别有自己的成员变量,而不同对象的成员变量各自有值,互不相干。但是,有时...1静态成员
如果定义了一个student类,定义 3 个student类的对象,如下:
student stud1, stud2, stud3;
那么,每一个student类对象都分别有自己的成员变量,而不同对象的成员变量各自有值,互不相干。但是,有时人们希望有一个或几个成员变量为所有对象所共有。这样,可以实现数据共享。
学习C语言时已经了解了全局对象,它能够实现数据共享。如果在一个程序文件中有多个函数,在每一个函数中都可以改变全局变量的值。全局变量的值为各个函数共享,但是,用全局变量时安全性得不到保证,由于在各处都可以自由地修改全局变量的值,很有可能偶到失误,全局变量的值就被修改,导致程序错误。因此,在实际工作中很少使用全局变量。
如果想在同类的多个对象之间实现数据共享,也不要用全局对象,可以用静态的成员变量。使用静态成员变量,实现数据共享。
2静态成员变量
2.1 静态成员变量的定义
静态成员变量是一种特殊的成员变量。它以关键字static开头,用static关键字来修饰的一种成员变量,例如:
class student
{
public:
char name[32]; //姓名
char addr[32]; //家庭地址
static long long number; //电话号码
public: //以下部分是公有部分
student(char* pn, char* pa)
{
strcpy(name, pn);
strcpy(addr, pa);
}
void print() const
{
cout << "name = " << name << endl;
cout << "addr = " << addr << endl;
cout << "number = " << number << endl;
}
};
此时,在student类中定义的number成员变量,就是“静态成员变量”。每个student类对象中的number的值都是一样的,把它定义为静态成员变量,这样它就为各对象所共有,而不只属于某个对象的成员,所有对象都可以引用它。
静态的成员变量在内存中只占一份空间(而不是每个对象都分别为它保留一份空间)。每个对象都可以引用这个静态成员变量。所有同类对象的静态成员变量的值都是一样的。如果改变它的值,那么,在各个对象中这个成员变量的值都同时改变了。这样,可以节省空间,提高效率。
静态成员变量是属于类,而不是属于某个独立对象。N个独立的对象,共享一个静态成员变量。
如下是一个测试例子:
程序运行结果如下:
可以看到,student类定义number成员是static类型。在类外给number成员初始化。然后,在stud对象中修改number成员的值。
然后,输出stud1对象的信息,得到的stud1. number成员变量是stud.number设置的值。所以,stud, stud1对象是共享static类型的number成员变量。
韦凯峰 Linux C/C++ 程序设计教程,Linux 系统编程,Openwrt 系统开发,微信:13926572996,QQ:1523520001,博客:www.mylinux.vip
-
c++静态成员变量的初始化
2021-10-20 17:13:40普通静态变量的初始化 #include<iostream> using namespace std; int main() { static int sa;//普通静态变量 ...c++静态成员变量的初始化 #include<iostream> using namespace std; class A {普通静态变量的初始化
#include<iostream> using namespace std; int main() { static int sa;//普通静态变量 //普通静态变量定义时分配内存,系统自动初始化为0 cout << sa << endl; return 0; }
静态成员变量的初始化
参考以下文章
c++静态成员变量的初始化#include<iostream> using namespace std; class A { public: static int cnt; }; int main() { A a; static int sa;//普通静态变量 cout << sa << endl;//0 cout << A::cnt << endl; cout << sizeof(A) << endl;//1 return 0; } /* 上述代码会报错,错误 2 error LNK2001: 无法解析的外部符号 "public: static int A::cnt" 原因是static int cnt只是类内的声明,在类外没有定义, 即没有分配内存,所以会报错 */
在类外加上静态数据成员的定义int A::cnt后,程序会通过编译。
#include<iostream> using namespace std; class A { public: static int cnt; }; int A::cnt;//静态数据成员的定义,分配内存,自动初始化为0 int main() { A a; static int sa;//普通静态变量 cout << sa << endl;//自动初始化为0 cout << A::cnt << endl;//自动初始化为0 cout << sizeof(A) << endl; return 0; }
总结:
这里普通静态变量与类的静态成员变量的初始化不同,原因是类的静态数据成员变量只是在类内进行声明,并没有为其分配内存空间,所以在类外必须定义,从而分配空间并初始化。而普通静态变量声明与定义是同时的,不用再另行定义。
-
C++静态成员
2017-03-15 12:55:48C++,静态成员 -
C++ 静态成员函数
2020-02-28 13:25:31在类中,static 不仅可以声明静态成员变量,还可以声明静态成员函数。 1、普通成员函数可以访问所有成员(包括成员变量和成员函数),而静态成员函数只能访问静态成员。 编译器在编译一个普通成员函数时,会隐式地... -
C++ 静态成员变量
2020-08-23 16:03:43静态成员变量 1、成员变量和成员函数前加上关键字static,称为静态成员。 2、静态成员变量:所有对象共享一份数据、在编译阶段分配内存、类内声明,类外初始化。 class Person { public: static int m_A; private: ... -
C++静态成员变量初始化
2021-06-17 10:35:00静态成员变量初始化 静态成员变量可以初始化,但只能在类体外进行初始化。如: long long student::number = 13926572996; //在类体外对静态成员变量赋值 其一般形式为: 数据类型 类名::静态成员变量名 = ... -
C++静态成员函数和普通成员函数的区别
2021-12-12 15:13:35** 静态成员函数和普通成员函数的区别 ** 根据成员函数的创建来看: 静态成员函数为类所有,当类加载创建时,会在内存代码区创建相应函数代码块。 而为了方便内存管理.普通成员函数只有在对象实例化时会在代码区创建... -
C++静态成员变量在内存中的存储方式
2021-06-17 10:36:10如果只声明了类而未定义对象,则类的一般成员变量是不占用内存空间的,只有在定义对象的时候,才为...但是,静态成员变量不属于某一个对象,在为对象分配空间中,不包括静态成员变量所占的空间。程序测试例子例如: ... -
C++ 静态成员的使用(整理)
2020-10-19 09:07:37C++中的静态成员(静态成员函数和静态数据成员)属于类所有,不属于类的对象,与普通的成员相比,静态成员无this指针。 静态成员变量 不同的对象占用不同的内存,这就使不同对象的成员变量相互独立,互不影响。... -
C++静态成员函数
2019-05-01 17:17:30一点睛 与静态数据成员不同,静态成员函数的作用...静态成员函数和非静态成员函数的根本区别:非静态成员函数有this指针,而非静态成员函数没有this指针。由此决定了静态成员函数不能访问本类中的非静态成员。 静...