静态类成员包括静态数据成员和静态函数成员两部分。
与全局变量相比,优势:
1. 静态数据成员仍然是在类域名字空间,没用进入程序的全局名字空间,因此不存在与程序中其他全局名字冲突的可能
2. 可以实现信息隐藏,静态数据成员可以是private成员,全局变量不行
静态数据成员:
静态数据成员必须在类定义外初始化,但const静态数据成员除外,const静态数据成员可以在类体中初始化
class c1
{
public:
private:
static int num;
static const string name = "chio";
};
int c1::num = 20;//类外定义并且初始化
const string c1::name ; //仍然需要在类体外定义
静态数据成员被 类 的所有对象所共享,包括该类派生类的对象。即派生类对象与基类对象共享基类的静态数据成员。
静态成员函数:
类成员函数(无论是static成员函数或非static成员函数)都可以直接访问static数据成员,但是static成员函数只能访问static数据成员。因为静态成员函数不含this指针。
non static member是属于对象级成员函数,也就是说,每个属于该类的对象都会产生一份属于自己的成员。而static member是属于类级成员,也就是说,无论该类产生多少个对象,而这种成员只会产生一个。为什么static member function只能访问static member data呢?就是因为static member data是属于类级成员数据,non static member data是属于对象级成员数据,而static member function是属于类级成员函数,non static member function是属于对象级成员函数。对于一个类级成员函数只能访问到类级成员数据。因为类级成员是共享的,而对象级成员是私有的,私有的数据只能是由私有函数来读取(可不要把这里的共享与私有的关系和灰的声明中的public与private的关系混淆了啊,这里的私有是指对象私有,而后者是指类私有)。
如果对于上面的解释还是不太好理解为什么类级成员只能访问类级成员数据的话,那我就用实际来告诉你为什么私有的对象数据不能由共享的函数来存取了。如有以下类的声明: private : 如果有以下函数的定义: 因为ptA和ptB都会产生属于对象自己的m_x(如果定义更多Point的对象,将会产生更多)。对于OutPut()是毫无疑问没问题的,因为ptA和ptB也会产生属于自己OutPut(),对象自己的函数访问属于对象自己数据,这是理所当然的。但Init()只会产生一个,而ptA和ptB都有属于自己m_x(各自互不侵犯),Init()怎么知道应该访问那个m_x呢(准确点应该说编译器怎么知道应该访问那个的m_x),还是对于所有Point的对象的m_x都进行存取呢(那不就是侵犯私隐了吗)。 正如前面所述的,ptA和ptB都会产生属于自己OutPut(),编译器怎么知道应该调用那个对象的OutPut()呢,对象级的函数自然只能使用对象级的调用方法了。对于Init()却是很好理解的,因为Init()由始至终只有一个,无论类级的调用,还是对象级的调用,都是合情合理的。 类的静态成员是属于类的而不是属于哪一个对象的,所以静态成员的使用应该是类名称加域区分符加成员名称的,在上面的代码中就是Point::Init,虽然我们仍然可以使用对象名加点操作符号加成员名称的方式使用,但是不推荐的,静态态类成员的特性就是属于类而不专属于某一个对象。
静态数据成员可以成为成员函数的可选参数,而普通数据成员则不可以: class base{ static数据成员的类型可以是其所属类,而非static数据成员类型只允许为该类的指针或引用:
class base{
class Point
{
public :
void OutPut ();
static void Init ( int, int );
int m_x;
static int m_y;
};
int Point::m_y = 10; //初始化static member data
Point ptA, ptB;
void
Point::OutPut () //正确
{
cout <<"x=" <<x <<endl
<<"y=" <<y <<endl;
}
void
Point::Init ( int x, int y )
{
m_x = x; //错误,m_x是对象级成员数据,Init()是类级成员函数
m_y = y; //正确,m_y和Init()都是类级成员
}
我们会经常以“类名::类成员函数”这种方法来调用一个函数(当然我不是说只有MFC都有这样的调用)。要使用这样的调用方法是需要有一个条件的,就是这个类成员函数一定要是一个static member function。如果你不明白前面的解释的话,你是不会想到这点的。那为什么一定要是static member function才能这样被调用呢,其实原理跟前面是一样的,就是因为static member function只会产生一个。如果你还是想不到为什么的话,那我就用实际来说明一切吧!沿用前面类的声明,如果有以下的用法:
Point::Init ( 5, 5 ); //正确(这里只讨论它的调用方法,不讨论它的定义是否正确),因为Init()是类级成员函数
ptA.Init ( 3, 3 ); //正确,既然Init()是共享的,ptA自然也可以用
Point::OutPut (); //错误,OutPut()是对象级成员函数
ptA.OutPut (); //正确,对象级的函数调用
public :
static int _staticVar;
int _var;
void foo1(int i=_staticVar);//正确,_staticVar为静态数据成员
void foo2(int i=_var);//错误,_var为普通数据成员 //_var不能独立于所属对象而使用。
};
2 {
3 public
4 //
5 private:
6 static Bar mem1;//ok
7 Bar *mem2;//ok
8 Bar mem3; //error
9 };
静态成员函数不可以同时声明为 virtual、const、volatile函数:
virtual static void func1();//错误
static void func2() const;//错误
static void func3() volatile;//错误
};
只在类体的函数声明前加static, 类体外函数定义不能指定关键字static
发表评论
-
set容器的反向迭代器
2013-05-02 16:56 3743#include <iostream> #in ... -
对于CRITICAL_SECTION用法的介绍和理解[转]
2013-04-08 11:50 2181很多人对CRITICAL_SECTION ... -
二维数组知识
2012-09-15 17:20 816二维数组和指针⑴ 用 ... -
Realloc的使用
2012-08-14 11:04 829realloc 用过很多次了。 ... -
extern C的由来
2012-08-09 10:14 695时常在cpp的代码之中看到这样的代码: #ifdef ... -
C++类对象的创建过程
2012-07-26 16:02 939分配空间(Allocation) ... -
复制构造函数(拷贝构造函数)以及深浅拷贝
2012-07-25 22:39 1429对于普通对象而言复制是很简单的,一般是将变量或者常量赋值给某 ... -
cin、cin.get、cin.getline()、getline()、gets()的用法【转】
2012-07-24 20:05 831学C++的时候,这几个输入函数弄的有点迷糊;这里做个小结,为了 ... -
编程笔记(07-24)
2012-07-24 15:15 6681 #include < stdio.h ... -
堆、栈解疑
2012-07-12 21:53 585一、预备知识—程序的内存分配 一个由C/C++编译的程序 ... -
指针和内存分配的深度理解
2012-07-12 18:57 1031一 :关于指针和堆的内存分配 先来介绍一下指针: 指针一种 ... -
数组指针和指针数组
2012-07-12 18:56 1187先看一下基本的形式,我们从这里起步! ----------- ... -
const指针和指向const的指针
2012-07-12 10:30 2120指向const对象的指针 ... -
typedef的学习
2012-07-11 15:03 739typedef,顾名思义,为“类型定义”,可以解释为:将一种数 ... -
函数指针和指针函数
2012-07-11 11:21 595【函数指针】 ... -
Define学习
2012-07-11 10:12 1073宏替换是C/C++系列语言的技术特色,C/C++语言提 ... -
sizeof 深研
2012-07-11 09:39 6671、什么是sizeof 首先看一下sizeof ... -
内存对齐问题
2012-07-10 22:35 10971.内存数据对齐的原因: 无论如何,为了提高程序的性 ... -
指针深究
2012-07-09 21:55 594在说指向指针的指针之前,不得不说指向变量的指针。先看如下示例: ... -
C语言文件使用方式详解
2012-07-04 10:23 768文件的打开(fopen函数) f ...
相关推荐
在编程中,静态数据成员和静态成员函数是类的一个重要特性,它们与普通的成员变量和成员函数有所不同。静态数据成员属于类,而不是类的每个实例,这意味着所有类的实例共享同一份静态数据成员的副本。这使得静态数据...
### C++类中的静态成员变量和静态成员函数的作用 #### 静态成员变量与静态成员函数概述 在C++编程语言中,类是面向对象编程的基础,它允许程序员定义包含数据成员(变量)和成员函数(方法)的复合数据类型。其中...
在C++编程语言中,静态数据成员和静态成员函数是面向对象编程中非常重要的概念,它们允许我们在类的范围内共享数据,而不是局限于单个对象。下面将详细解释这两个概念。 首先,静态数据成员(Static Data Members)...
在C++编程中,"静态"一词有多种含义,主要涉及到静态全局变量、静态数据成员和静态成员函数。这些特性在程序设计中扮演着重要角色,尤其在数据结构和算法实现时。以下是对这些概念的详细解释: 1. 静态全局变量: ...
静态成员在C++中扮演着重要的角色,包括静态数据成员和静态函数成员两部分。静态成员是指在类体中使用static修饰符声明的成员,可以直接使用类名+静态成员名访问该静态成员。静态成员存在于内存中,而非静态成员需要...
静态成员分为静态数据成员和静态成员函数。在标题“全局数据管理—使用C++类的静态成员取代全局数据”中,重点在于静态数据成员。静态数据成员是类的一个共享属性,不与任何特定的对象关联,所有该类的对象共享同一...
正确理解和使用静态数据成员是成为熟练的C++程序员的关键。同时,注意静态成员的初始化位置,避免因重复定义而导致的编译错误。在实际编程中,结合具体需求,灵活运用这些知识,可以提升代码的效率和可维护性。
- **访问性**:静态数据成员遵循类的访问修饰符,可以被类的非静态成员函数和静态成员函数以及类的友元访问。 - **共享性**:无论创建多少个对象,静态数据成员的值都是共享的,修改一个对象的静态数据成员会影响...
在C++中,静态成员分为静态数据成员和静态成员函数。静态数据成员是类的所有实例共享的,这意味着不论创建多少个对象,静态数据成员只占用内存中的一份空间。静态成员函数则不与任何特定对象关联,它可以访问类的...
1.编写一个类,声明一个数据成员和一个静态数据成员,其构造函数初始化数据成员,并把静态数据成员加1,其析构函数把静态数据成员减1。 (1) 编写一个应用程序,创建该类的3个对象,然后显示其数据成员和静态数据成员...
易语言是一种专为中国人设计的编程语言,它以简明直观的中文语法,降低了编程的门槛,...静态数据成员在设计和实现一些需要全局共享状态或计数器等功能时非常有用,但应谨慎使用,避免造成不必要的复杂性和潜在的问题。
静态成员函数可以分为两部分:静态数据成员和静态函数成员。 一、静态数据成员 静态数据成员是类中的全局变量,它们遵守public、protected和private访问规则。静态数据成员的定义需要在cpp文件中进行,而不能在...
在没有讲述本章内容之前如果我们想要在一个范围内共享某一个数据,那么我们会设立全局对象,但面向对象的程序是由对象构成的,我们如何才能在类范围内共享数据呢? 这个问题便是本章的重点:
静态成员有静态数据成员和静态成员函数之分。 十五点一 静态成员的需要性 在某些情况下,类的所有对象需要共享某些资源,例如学生人数、学生类链表首指针等。这种情况下,使用静态成员可以实现资源共享。静态...
静态成员分为静态数据成员和静态成员函数。 1. **静态数据成员**: - 它们不是每个对象的专属属性,而是属于类本身。 - 静态数据成员的初始化是在类的外部完成的,使用类名和作用域解析运算符::进行初始化,例如...
一般地,线程要读写类的私有成员变量,只有两种方法:将全局函数声明为类友元friend,或者使用静态的成员函数static。...本例就是自己的研究成果,使用非静态的成员函数作为线程函数,还能修改类的非静态的数据成员。
本资源摘要信息将详细介绍 C++ 程序设计中的静态成员和友元,包括静态成员的需要性、静态成员的使用、静态数据成员、静态成员函数、友元的需要性和友元的使用。 静态成员的需要性 在面向对象编程中,类的所有对象...
编写一个类,声明一个数据成员和一个静态数据成员:(1)让构造函数初始化数据成员,并把静态成员加1,让析构函数把静态成员...(3)添加一个静态成员函数,并用它来访问静态数据成员,再次,使静态数据成员为保护的。
静态成员分为静态数据成员和静态成员函数。 1. **静态数据成员**: 静态数据成员是类级别的变量,不隶属于任何特定的对象。在上面的例子中,`Student`类有一个静态数据成员`noOfStudents`,用于记录创建的学生对象...