1、静态成员函数、静态数据成员

在类中,用static修饰的成员函数被称为静态成员函数,而用static修饰的数据成员就称为静态数据成员;与普通的成员函数和数据成员不同,

静态成员函数和静态数据成员有自己独有的特点和用法,定义方法如下:

  class Tank{
public:
static void func(void); // 声明静态成员函数
..........
private:
static int m_iCount; // 声明静态数据成员
.......
} int Tank::m_iCount = ; // 初始化静态数据成员 void Tank::func(void) // 定义静态成员函数 注意不要加 static
{
.....
}

2、静态成员函数、静态数据成员与普通的成员函数、数据成员有什么区别?

(1)静态成员函数、静态数据成员依赖于具体的类,但是并不依赖于类实例化的对象。

当一个类定义完成之后,我们其实就可以调用这个类的静态成员函数和静态数据成员,而不必实例化一个类对象之后才能使用,

这点与非静态的成员函数和非静态的数据成员是不同的。例如下面所示:

 #include <iostream>
using namespace std; class Tank{
public:
Tank(void) { m_iCount++; }
~Tank(void) { m_iCount--; }
static void func(void); // 申明静态成员函数
static int m_iCount; // 声明静态数据成员
}; ......... // 省略了初始化静态数据成员和静态成员函数定义 int main(void)
{
Tank::func(); // 没有实例化类对象而直接使用静态成员函数
cout << Tank::m_iCount << endl; // 没有实例化类对象而直接使用静态数据成员
return ;
}

(2)静态成员函数不能调用非静态成员函数和非静态成员数据,但是非静态成员函数可以调用静态成员函数和静态成员数据。

这个其实是很好理解的,前面说过,静态成员函数、静态数据成员不依赖于实例化对象,只是随着类定义的出现而存在;

但是非静态数据成员必须是实例化一个具体的对象之后才存在一份属于这个对象的成员数据,而非静态成员函数虽然代码只有一份,

但是因为函数操作的成员数据是依赖于具体的对象的,所以导致成员函数也是依赖于对象的;所以在这种情况下,静态成员函数

是不能操作非静态数据成员和非静态成员函数的,因为先于非静态数据成员诞生,先于非静态成员函数被"激活",就好比是

:你都不知道后面会定义哪些具体的对象,你怎么能够提前就使用呢?但是静态成员函数是可以调用的静态数据成员的。

(3)静态数据成员在内存中只有一份,而非静态数据成员依赖于具体的对象,所以不同的对象都有一份非静态数据成员。

(4)静态数据成员必须单独初始化,不能在类构造函数中进行初始化,实例化类的大小中并不包括静态数据成员。

类的构造函数是实例化一个对象的时候才调用的,而静态数据成员不依赖于对象,所以不能使用构造函数来初始化一个静态数据成员。

 #include <iostream>
using namespace std; class Tank{
public:
Tank(char name) { m_cName = name; m_iCount++; } // 构造函数
~Tank(void) { m_iCount--; } // 析构函数
int getCount(void) { return m_iCount; }
static int func(void); // 申明静态成员函数
private:
char m_cName;
static int m_iCount; // 声明静态数据成员
}; int Tank::m_iCount = ; // 静态数据成员的初始化 int Tank::func(void)
{
return m_iCount;
cout << "Tank---func" << endl;
} int main(void)
{
Tank tank('A');
cout << sizeof(tank) << endl; // 测试大小
cout << Tank::func() << endl;
return ;
}

静态数据成员的初始化

(5)调用静态成员函数、静态数据成员与调用非静态成员函数、非静态数据成员不同。

静态成员函数、静态数据成员的调用方式有两种:在还没有实例化对象前 和 实例化对象之后,,代码如下:

 #include <iostream>
using namespace std; class Tank{
public:
Tank(char name) { m_cName = name; m_iCount++; } // 构造函数
~Tank(void) { m_iCount--; } // 析构函数
int getCount(void) { return m_iCount; }
static int func(void); // 申明静态成员函数
private:
char m_cName;
static int m_iCount; // 声明静态数据成员
}; int Tank::m_iCount = ; // 静态数据成员的初始化 int Tank::func(void)
{
return m_iCount;
cout << "Tank---func" << endl;
} int main(void)
{
cout << Tank::func() << endl; // 实例化对象之前 Tank tank('A'); cout << tank.func() << endl; // 实例化对象之后,也可以是 Tank::func() 两种都可以 return ;
}

调用非静态的方法

(6)在静态成员函数的参数列表中是没有带默认的this指针的,因为this指针是用来指向这个对象的地址的,而我们的静态成员函数不依赖于实例化对象而存在,所以是没有thsi指针的。

所以在函数声明的后面也是不能加上const来进行修饰的,否则编译是会出错的。

在C++中,本人对于 :: 和 . 的理解:   class Time;

:: 前面的一般都是一种数据类型,可以是结构体类型和类类型,例如 Time::func(); 表示func这个函数依赖于类(也就是数据类型),并不依赖与对象(也就是具体的变量);

. 前面的一般都是一个具体的对象(也就是变量),例如 Time time;  time.set(); 表示set函数依赖于这个对象(也就是变量),既然依赖于这个具体的对象;

以上纯属我自己的理解。

C++中static修饰的静态成员函数、静态数据成员的更多相关文章

  1. C++学习5-面向对象编程基础(构造函数、转换构造、静态数据成员、静态成员函数、友元)

    知识点学习 类 const作用 C语言的const限定符的含义为"一个不能改变值的变量",C++的const限定符的含义为"一个有类型描述的常量": const ...

  2. C++基础(静态数据成员和静态成员函数)

    [简介] 1.静态数据成员在类中声明,在源文件中定义并初始化: 2.静态成员函数没有this指针,只能访问静态数据成员: 3.调用静态成员函数:(1)对象.(2)直接调用: 4.静态成员函数的地址可用 ...

  3. C++ 静态数据成员和静态成员函数

    一 静态数据成员: 1.静态数据成员的定义. 静态数据成员实际上是类域中的全局变量.所以,静态数据成员的定义(初始化)不应该被放在头文件中,因为这样做会引起重复定义这样的错误.即使加上#ifndef ...

  4. C++静态数据成员与静态成员函数

    一般情况下,如果有n个同类的对象,那么每一个对象都分别有自己的数据成员,不同对象的数据成员各自有值,互不相干.但是有时人们希望有某一个或几个数据成员为所有对象所共有,这样可以实现数据共享. 可以使用全 ...

  5. 转:C语言中的static变量和C++静态数据成员(static member)

    转自:C语言中的static变量和C++静态数据成员(static member) C语言中static的变量:1).static局部变量        a.静态局部变量在函数内定义,生存期为整个程序 ...

  6. 静态数据成员(面向对象的static关键字)

    静态数据成员: 在类内数据成员的声明前加上关键字static,该数据成员就是类内的静态数据成员.先举一个静态数据成员的例子. #include<iostream> using namesp ...

  7. C++类中static修饰的函数的使用

    //在C++中应该养成习惯:只用静态成员函数引用静态成员数据,而不引用非静态成员数据 #include <iostream>using namespace std;class st_inf ...

  8. C++类静态数据成员与类静态成员函数

    from:://http://blog.csdn.net/taina2008/article/details/1684834 把类中的函数都定义成静态函数,这样相当于在编译时就分配了空间,这样不需要实 ...

  9. 《挑战30天C++入门极限》C++类静态数据成员与类静态成员函数

        C++类静态数据成员与类静态成员函数 在没有讲述本章内容之前如果我们想要在一个范围内共享某一个数据,那么我们会设立全局对象,但面向对象的程序是由对象构成的,我们如何才能在类范围内共享数据呢? ...

随机推荐

  1. Spring4源码解析:BeanDefinition架构及实现

    一.架构图 首先共同看下总体的 Java Class Diagrams 图: 二.具体类实现 2.1 AttributeAccessor 接口定义了一个通用的可对任意对象获取.修改等操作元数据的附加契 ...

  2. myeclipse越来越卡了怎么回事啊?

    去掉拼写检查:windows->preferences->General->Editors->Text Editors->Spelling 将“Enable spell ...

  3. SpringBoot2.0 url中出现特殊符号「带括号{}'"等等」时会抛出400错误

    访问 http://127.0.0.1:8080/api?method=taxiong.goods.list&params={"page":1,"pageSize ...

  4. 02 - Unit09:动态SQL

    动态SQL 什么是? 系统运行过程中,动态生成的SQL语句 为什么? 当我们不能确定用户操作,所要使用的具体SQL的时候. 案例: 搜索笔记功能 按用户名 笔记本名 笔记名 搜索 搜索功能 按用户 A ...

  5. QT 控制LED实验

    1.实验准备 在PC 机D:盘下创建文件夹qt-led,将光盘qt_led_exp 文件夹下的images 文件夹拷贝到E:盘下qt-led 文件夹qt-led 内 2.新建工程 新建一个Empty ...

  6. Serv-u只开放21端口连接不上解决方案

    在Serv-U的Local Server -> Settings -> Advanced -> PASV port range里, 填入给PASV模式使用的本地端口范围,如60000 ...

  7. SecureCRT 上传/下载文件到Linux服务器

    1. 安装上传/.下载软件 a) cd /tmp wget http://www.ohse.de/uwe/releases/lrzsz-0.12.20.tar.gz tar zxvf lrzsz-0. ...

  8. 使用GridFsTemplate在mongodb中存取文件

    spring-data-mongodb之gridfs   mongodb除了能够存储大量的数据外,还内置了一个非常好用的文件系统.基于mongodb集群的优势,GridFS当然也是分布式的,而且备份也 ...

  9. Django---Xss过滤以及单例模式

    Xss过滤 在表单填写的过程中我们就用到textarea,富文本编辑框,里面要用户输入相关的内容.如果有的人想要搞怪,在里面写一些js代码或者修改编辑的时候修改源代码,那提交上去之后就会使得页面显示不 ...

  10. uwsgi配置文件的一些细节,uwsgi错误invalid request block size

    [uwsgi] #socket = #这种是使用代理方式访问的,不能直接输入端口访问,要搭配其他的HTTP服务比如NGINX,设置反向代理 http =: #这种是直接可以输入IP端口访问 modul ...