C++基础--静态成员
2008-09-02 14:46
190 查看
C++基础--静态成员(1)
C++基础--静态成员(2)
前面我们已经看到:每一个类对象有其公有或私有的数据成员,每一个public或private函数可以访问其数据成员。 有时,可能需要一个或多个公共的数据成员,能够被类的所有对象共享。在C++中,我们可以定义静态(static)的数据成员和成员函数。 10.6.1 静态数据成员 要定义静态数据成员,只要在数据成员的定义前增加static关键字。静态数据成员不同于非静态的数据成员,一个类的静态数据成员仅创建和初始化一次,且在程序开始执行的时候创建,然后被该类的所有对象共享;而非静态的数据成员则随着对象的创建而多次创建和初始化。 下面是静态数据成员定义的实例:
类名::静态数据成员名 但是,不能直接访问私有的数据成员。其实,上面的程序段只是为了介绍如何访问静态数据成员,不能通过编译器的的编译和连接。 一、私有的静态数据成员 为了说明私有的静态数据成员的使用,考虑下面的程序段: class Directory { public: ... private: // 数据成员 static char path[]; }; 数据成员path[]是一个私有的静态变量,在程序执行过程中,仅一个Directory::path[]存在,即使有多个Directory类的对象。静态的数据成员能够被类的成员函数访问,但不能在构造函数中初始化。这是因为静态数据成员在构造函数被调用之前就已经存在了。静态数据成员可以在定义时初始化,且必须在类和所有的成员函数之外,与全局变量初始化的方法一样。例如,类Directory的数据成员的定义与初始化方法如下: // 静态数据成员的定义与初始化 char Directory::path [200] = "/usr/local"; // 无参的构造函数 Directory::Directory() { ... } 在类中的静态数据成员的定义,只是说明该类有这么一个数据成员,并没有为该数据成员分配内存。就象非静态数据成员是在创建对象时分配内存一样,静态数据成员是在初始化时分配内存的。所以,在定义静态的数组成员时,可以省略它的尺寸(数组元素的个数),但在初始化时,必须确定数组的尺寸。 二、公有的静态数据成员 数据成员也可以是公有的,不过我们很少定义公有的数据成员,因为它破坏了数据隐藏的原则。如果Directory类的成员path[]定义为公有的,则该成员可在类外的任一地方访问: void main() { strcpy(Directory::path, "/usr/local/pub"); //修改path的值 … } path仍然必须先初始化: char Directory::path[200]; 为什么需要静态数据成员? 类的静态数据成员拥有一块单独的存储区,而不管我们创建了多少个该类的对象。也就是说,静态数据成员被类的所有对象共享,它是属于类,而不是属于对象的。所有对象的静态数据成员都共享一块静态存储空间,可以节省内存,也为对象之间提供了一种互相通信的方法。静态数据成员的作用域在类内,也有public(公有)、private(私有)或者protected(保护)三种访问权限。 静态数据成员的存储空间分配 对于非静态数据成员而言,有多少个对象,就有多少个不同的内存单元,它们分布在各个对象的存储空间中。静态数据成员不同于非静态数据成员,不管有多少个对象,它们都共享相同的内存单元。所以,静态数据成员不应该属于任何一个对象,说它属于类更确切。 我们用一个例子来说明这种存储空间的关系, 对于类: class C { static int si; static int sc; int i; char c; //…… }; 如果我们创建了类C的三个对象c1、c2和c3,那么它们的数据成员的存储关系如图10-2所示:
静态数据成员的初始化必须在类外,例如: class A { static int i; public: //…… }; 静态数据成员i的初始化方法为:"int A::i=1;"。可见:它与全局变量的初始化的方法的不同之处在于,有类名和作用域分隔符指定i的范围。 我们还可以定义静态的数组成员,例如:
成员常量 我们先看下面一个实例: class A { const size = 100; //illegal int array[size]; //illegal }; 类A是想定义一个常量数组,但这个类的定义是错误的。因为定义类常量数据成员时,不能同时进行初始化。定义类时,只是说明类有那些数据成员,而不涉及到内存单元的分配,类数据成员存储单元的分配是在对象初始化时进行的。 我们也可以把常量数据成员定义成静态的,同静态成员变量初始化一样,静态成员常量初始化也在类外,例如:
可以很容易地把一个静态数据成员放在一个嵌套类中,它是非嵌套类中静态数据成员情况的扩展,只将它的范围进行另一个级别的指定就可以了。然而,在局部类(如在函数内部定义的类)中不能有静态数据成员。例如:
|
2 静态成员函数 除静态数据成员外,C++也允许定义static成员函数。静态的数据成员被所有的对象共享,也就是说,静态数据成员不属于对象,而是属于类的。与静态数据成员类似,静态成员函数也是属于类的。 注意:静态成员函数仅能访问静态的数据成员,不能访问非静态的数据成员,也不能访问非静态的成员函数,这是由于静态的成员函数没有this指针。类似于静态的数据成员,公有的、静态的成员函数在类外的调用方式为: 类名::成员函数名(实参表) 不过,也允许用对象调用静态的成员函数。 下面举一个例子说明静态成员函数的调用方法:
需要注意的是:静态的成员函数仅能访问静态的变量和静态的成员函数,不能访问非静态的数据成员和非静态的成员函数。 静态成员函数 我们也可以创建一个静态的成员函数。同静态数据成员类似,它也是属于类,而不是属于某一个对象的。 静态成员函数不能访问非静态的数据成员,它只能访问静态数据成员,也只能调用其它的静态成员函数。原因是:当前对象的地址(this)是被隐含地传递到被调用的函数的。但一个静态成员函数没有this指针,所以它无法访问非静态的成员函数。 下面是一个应用静态数据成员和静态成员函数的例子:
类名::静态成员函数名(); 但也允许用对象或指向对象的指针调用。例如,在main()中,静态成员函数f分别被对象x和指向x对象的指针pX调用。 下面是一个有趣的例子:类egg有一个静态数据成员E和静态成员函数instance,instance的返回类型是指向egg对象的指针,类的构造函数是私有的。显然,我们不能创建该类的对象。但是该类确有一个对象存在,我们可以访问那个对象,也可以通过该对象访问其成员函数:
|
相关文章推荐
- 【C++基础学习】关于C++静态成员函数和变量
- C++基础(二)C/C++中的静态、非静态成员函数、变量
- C++语法基础--恢复继承成员的访问级别,默认继承保护级别,友元关系与继承,继承与静态成员
- C++语言基础 例程 静态成员
- [C++基础]C++中静态成员函数如何访问非静态成员
- C++基础4:构造函数、析构函数、拷贝构造函数、静态成员函数
- 【C++基础】浅谈内联、静态成员和友元
- c++基础学习8-类的静态成员
- 嵌入式开发之C++基础学习笔记5--静态成员,友元,运算符重载,模板,文件流
- C++学习5-面向对象编程基础(构造函数、转换构造、静态数据成员、静态成员函数、友元)
- [c++基础]运算符重载,共有数据保护,静态成员
- 【C++基础学习】关于C++静态数据成员
- 【C++基础学习】关于C++静态数据成员
- [C++基础]C++中静态成员函数如何访问非静态成员
- C++基础(七)静态成员
- C++基础学习笔记----第十一课(类的静态成员、对象模型初步认识)
- 【C++基础学习】关于C++静态成员函数和变量
- C++基础 静态成员,析构函数显示调用 课本5.1
- C++基础--static静态成员
- C++ 静态成员函数的特性