C++中类的静态成员介绍

本文主要介绍C++中类的静态成员的相关内容。

1 概述

在c++中,我们可以使用 static 关键字来把类成员声明为静态的。当我们将类的成员声明为静态时,就意味着无论创建多少个类的对象,该静态成员都只会存在一个副本。

2 静态成员变量

如果不存在其他的(对于静态成员变量的)初始化语句,那么在创建第一个对象时,类中的所有的静态成员变量都会被初始化为 0。 此结论貌似不准确,通过示例可以看到,以 classname objname(..) 方式创建对象时,并不会对类中的静态成员数据进行初始化。

静态成员变量的初始化:不能把静态成员变量的初始化操作放在类的定义中,但可以在类的外部,通过使用作用域运算符“::”来重新声明静态成员变量从而对它进行初始化。

静态成员变量在类的所有对象中是共享的。

2.1 示例1

下面通过一个代码示例,介绍类的静态成员变量的特性。示例代码(static_test1.cpp)如下:

#include 

using namespace std;

class Box
{
public:
    // 声明静态成员变量
    static int objectCount;
    // 构造函数定义
    Box(double l=2.0, double b=2.0, double h=2.0)
    {
        cout <<"Constructor called." << endl;
        length = l;
        breadth = b;
        height = h;
        
        // 每次创建对象时,静态成员变量 objectCount 加1
        objectCount++;
    }
    // 求立方体的体积
    double Volume()
    {
        return (length * breadth * height);
    }

private:
    double length;     // 长度
    double breadth;    // 宽度
    double height;     // 高度
};

// (定义并)初始化类 Box 的静态成员变量
int Box::objectCount = 0;

int main()
{
    Box Box1(3.3, 1.2, 1.5);    // 创建对象box1
    Box Box2(8.5, 6.0, 2.0);    // 创建对象box2

    // 输出已创建的对象的总数
    cout << "Total objects count is: " << Box::objectCount << endl;

   return 0;
}

编译并执行上述代码,结果如下:

通过示例代码及其运行结果,能够知道:

  • 类Box中的静态成员变量objectCount是在类外手动进行的初始化,如果将该行注释掉,则会报错,错误信息如下:
    C++中类的静态成员介绍_第1张图片
    这说明在上述示例代码中,创建对象时,类中的静态成员变量并未进行初始化;
  • 类Box中的的静态成员变量objectCount在对个对象中共用一个副本,所以创建两个对象后,objectCount的值变为2了。

2.2 示例2

这里再展示一个静态成员变量的用法示例,在本示例中,我们通过使用类的静态成员变量,能够跟踪类的构造与析构函数的调用情况

示例代码(static_test2.cpp)如下:

#include 

using namespace std;

class Cpoint
{
public:
    // 声明静态成员变量
    static int m_nConsTime;
    static int m_nDesTime;
    // 构造函数定义
    Cpoint(int x, int y)
    {
        xp = x;
        yp = y;
        // 每次创建对象时,静态成员变量 m_nConsTime 加1
        m_nConsTime++;
        cout << "[Cpoint] Constructor called: " << m_nConsTime << endl;
    }
    
    // 析构函数定义
    ~Cpoint()
    {
        // 每次调用析构函数时,静态成员变量 m_nDesTime 加1
        m_nDesTime++;
        cout << "[Cpoint] Destructor called:" << m_nDesTime << endl;
    }

private:
    int xp;
    int yp;
};

// (定义并)初始化类的静态成员变量
int Cpoint::m_nConsTime = 0;
int Cpoint::m_nDesTime = 0;

class CRect
{
public:
    // 构造函数定义
    CRect(int x1, int x2):mpt1(x1, x2), mpt2(x1, x2)
    {
        cout << "[CRect] Constructor called." << endl;
    }
    
    // 析构函数定义
    ~CRect()
    {
        cout << "[CRect] Destructor called." << endl;
    }
    
private:
    // 创建类Cpoint对象mpt1和mpt2
    Cpoint mpt1, mpt2;
};

int main()
{
    // 创建类CRect对象p
    CRect p(10,20);
    
    cout << "Hello, world!" << endl;
    
    return 0;
}

编译并执行上述代码,结果如下:

C++中类的静态成员介绍_第2张图片

3 静态成员函数

把类的成员函数声明为静态的,就可以把函数与类的任何特定对象独立开来。

类的静态成员函数的特点:

  • 即使在类对象不存在的情况下,静态成员函数也能被调用——静态成员函数只要使用类名加作用域运算符“::”就可以访问了;
  • 类的静态成员函数只能访问类的静态成员数据、类的其他静态成员函数和类外部的其他函数;
  • 静态成员函数有一个类范围,它不能访问类的 this 指针;
  • 可以使用静态成员函数来判断类的某些对象是否已被创建了;
  • 静态成员函数是类的一部分,但是不是对象的一部分。如果要在类外调用公用的静态成员函数,要用类名和作用域运算符“::”(如 Box::volume();),也可以通过对象名调用静态成员函数(如 a.volume();),但是这并不意味着此静态成员函数属于对象a(只是用了 a 的类型而已);
  • 静态成员函数不属于对象,它与任何对象都是无关的,因此静态成员函数没有 this 指针,也就是说:非静态成员函数有 this 指针,而静态成员函数没有 this 指针。由此决定了静态成员函数不能直接访问本类中的非静态成员。静态成员函数可以直接引用本类中的静态数据成员,因为静态数据成员同样是属于类的。当然,并不是说静态成员函数绝对不能访问本类中的非静态成员,只不过是不能进行默认访问(因为静态成员函数无法知道应该去找哪个对象的非静态成员),如果非要引用本类中的非静态成员,应该加上具体的对象名以及成员运算符“.”(例如:cout<

静态成员函数与普通成员函数的区别:

  • 普通成员函数有 this 指针,可以访问类中的任意成员;而静态成员函数没有 this 指针;
  • 静态成员函数没有 this 指针,只能访问类的静态成员(包括静态成员变量和静态成员函数)、以及类外部的其他函数。

3.1 示例1

下面通过一个示例代码,理解一下类的静态成员函数的概念。示例代码(static_test3.cpp)如下:

#include 

using namespace std;

class Box
{
public:
    // 声明静态成员变量
    static int objectCount;
    // 构造函数定义
    Box(double l=2.0, double b=2.0, double h=2.0)
    {
        cout <<"Constructor called." << endl;
        length = l;
        breadth = b;
        height = h;
        // 每次创建对象时 objectCount 加 1
        objectCount++;
    }
    // 求立方体的体积
    double Volume()
    {
        return (length * breadth * height);
    }
    // 获取已创建的类对象个数
    static int getCount()
    {
        return objectCount;
    }
    
private:
    double length;     // 长度
    double breadth;    // 宽度
    double height;     // 高度
};
 
// (定义并)初始化类 Box 的静态成员变量objectCount
int Box::objectCount = 0;

int main(void)
{
    // 创建对象前,输出已创建的对象的总数
    cout << "Inital Stage Count is: " << Box::getCount() << endl;
    
    Box Box1(3.3, 1.2, 1.5);    // 创建对象box1
    Box Box2(8.5, 6.0, 2.0);    // 创建对象box2
    
    // 创建对象后,输出已创建的对象的总数
    cout << "Final Stage Count is: " << Box::getCount() << endl;
    
   return 0;
}

编译并执行上述代码,结果如下:

在上述示例及执行结果中,我们能够看到,类 Box 的静态成员函数 getCount() 调用了该类的静态成员变量 objectCount 。

 

你可能感兴趣的:(C/C++语言)