类的静态成员变量及函数(二十)

        我们正常情况下能通过对象名来访问 public 成员变量,每个对象的成员变量都是专属的,成员变量不能在对象之间共享的。我们现在学了这么长时间的 C++,现在又有了一个新的需求:a> 同级在程序运行期间某个类的对象数目;b> 保证程序的安全性(不能使用全局变量);c> 随时可以获取当前对象的数目。

成都创新互联公司是专业的灵宝网站建设公司,灵宝接单;提供成都网站制作、成都做网站,网页设计,网站设计,建网站,PHP网站建设等专业做网站服务;采用PHP框架,可快速的进行灵宝网站开发网页制作和功能扩展;专业做搜索引擎喜爱的网站,专业的做网站团队,希望更多企业前来合作!

        我们首先想到的是定义一个私有成员变量,然后在构造函数中进行 ++ 操作,在析构函数中进行 -- 操作。我们试着写下程序

#include 

class Test
{
private:
    int mCount;
public:
    Test()
    {
        mCount++;
    }
    ~Test()
    {
        --mCount;
    }
    int getCount()
    {
        return mCount;
    }
};

Test gTest;

int main()
{
    Test t1;
    Test t2;
    
    printf("gTest.getCount() = %d\n", gTest.getCount());
    printf("t1.getCount() = %d\n", t1.getCount());
    printf("t2.getCount() = %d\n", t2.getCount());
    
    return 0;
}

        我们先来试着编译下

类的静态成员变量及函数(二十)

        那么它打印出来的是都是随机值,我们在构造函数中的初始化列表中进行初始化为0

类的静态成员变量及函数(二十)

        我们看到打印出三个 1,并不是我们所期望的三个 3。这是因为在每次新生成对象调用构造函数时,它都会初始化。那么我们试着定义一个全局变量来试试呢,int gMount = 0

类的静态成员变量及函数(二十)

        显然它是可以满足的,但是我们的客户需求里有一条便是不准使用全局变量。所以这个只得放弃。这时我们便想到了静态成员变量,下来我们来讲讲静态成员变量。在 C++ 中可以定义静态成员变量:a> 静态成员变量属于整个类所有;b> 静态成员变量的声明周期不依赖于任何对象;c> 可以通过类名直接访问共有静态成员变量;d> 所有对象共享类的静态成员变量;e> 可以通过对象名访问公有静态成员变量。静态成员变量的特性:1、在定义时直接通过 static 关键字修饰;2、静态成员变量需要在类外单独分配空间;3、静态成员变量在程序内部位于全局数据区。它的语法规则是:Type ClassName::VarName = value;

        下来我们使用静态成员变量来看看是否会满足要求,程序如下

#include 

class Test
{
private:
    static int mCount;
public:
    Test() : mCount(0)
    {
        mCount++;
    }
    ~Test()
    {
        --mCount;
    }
    int getCount()
    {
        return mCount;
    }
};

Test gTest;

int main()
{
    Test t1;
    Test t2;
    
    printf("gTest.getCount() = %d\n", gTest.getCount());
    printf("t1.getCount() = %d\n", t1.getCount());
    printf("t2.getCount() = %d\n", t2.getCount());
    
    return 0;
}

        我们编译下看看

类的静态成员变量及函数(二十)

        我们看到报错了,要在全局数据区进行初始化,我们加上 int Test::mCount = 0;并且去掉构造函数中初始化列表的初始化,再次编译

类的静态成员变量及函数(二十)

        我们看到已经实现了哈,那么我们是否可以放心的交给用户了哈。仔细看下,我们的程序没完成第三条需求,随时可以获取当前对象的数目。如果我们没有定义对象的话,那么我们这个程序是否还可以完成功能呢?肯定不行了。

        那么我们尝试将 mCount 属性改为 public 呢,看看是否可以满足,程序如下

#include 

class Test
{
public:
    static int mCount;
public:
    Test()
    {
        mCount++;
    }
    ~Test()
    {
        --mCount;
    }
    int getCount()
    {
        return mCount;
    }
};

int Test::mCount = 0;

int main()
{
    printf("mCount = %d\n", Test::mCount);
    
    return 0;
}

        结果如下

类的静态成员变量及函数(二十)

        我们看到当没有定义对象的时候,它的数目是 0。但是这样做是不安全的,我们在 main 函数中将 mCount 手动改为 100,看看结果还是 0 吗?

类的静态成员变量及函数(二十)

        我们看到它变成 100 了。也就是说,这是不安全的。所以这个方法不可取。那么我们这时就需要分析问题了,我们需要什么呢?不依赖对象就可以访问静态成员变量,必须保证静态成员变量的安全性,方便快捷的获取静态成员变量的值。在 C++ 中可以定义静态成员函数:a> 静态成员函数是类中特殊的成员函数;b> 静态成员函数属于整个类所有;c> 可以通过类名直接访问公有静态成员函数;d> 可以通过对象名访问公有静态成员函数。它的定义便是直接通过 static 关键字修饰成员函数。

        下来我们试试静态成员函数,程序如下

#include 

class Demo
{
private:
    int i;
public:
    int getI();
    static void staticFunc(const char* s);
    static void staticSetI(Demo& d, int v);
};

int Demo::getI()
{
    return i;
}

void Demo::staticFunc(const char* s)
{
    printf("staticFunc: %s\n", s);
}

void Demo::staticSetI(Demo& d, int v)
{
    d.i = v;
}

int main()
{
    Demo::staticFunc("mian begin...");
    
    Demo d;
    
    Demo::staticSetI(d, 10);
    
    printf("d.i = %d\n", d.getI());
    
    Demo::staticFunc("mian end...");
    
    return 0;
}

        结果如下

类的静态成员变量及函数(二十)

        那么我们试试能否直接在 staticSetI 函数中对 i = v 呢?(去掉 Demo& d),我们试试类的静态成员变量及函数(二十)

        它报错了,因为静态成员函数不能直接访问普通成员变量。下面我们关于静态成员函数和普通成员函数的区别做了一个对比,如下图所示

类的静态成员变量及函数(二十)

        那么关于我们之前提出的需求,我们可以利用静态成员函数来满足,程序如下

#include 

class Test
{
private:
    static int mCount;
public:
    Test()
    {
        mCount++;
    }
    ~Test()
    {
        --mCount;
    }
    static int getCount()
    {
        return mCount;
    }
};

int Test::mCount = 0;

int main()
{
    printf("mCount = %d\n", Test::getCount());
    
    Test t1;
    Test t2;
    
    printf("t1.getCount() = %d\n", t1.getCount());
    printf("t2.getCount() = %d\n", t2.getCount());
    
    Test* pt = new Test();
    
    printf("t2.getCount() = %d\n", pt->getCount());
    
    delete pt;
    
    printf("t2.getCount() = %d\n", pt->getCount());
    
    return 0;
}

        我们看看编译结果

类的静态成员变量及函数(二十)

        我们看到已经满足客户的需求了。通过对静态成员变量和函数的学习,总结如下:1、类中可以通过 static 关键字定义静态成员变量;2、静态成员变量隶属于类所有,每一个对象都可以访问静态成员变量;3、静态成员变量在全局数据区分配空间,它的生命周期为程序运行期;4、静态成员函数是类中特殊的成员函数;5、静态成员函数没有隐藏的 this 指针,它可以通过类名直接访问;6、静态成员函数只能直接访问静态成员变量(函数)。

        欢迎大家一起来学习 C++ 语言,可以加我QQ:243343083。


分享文章:类的静态成员变量及函数(二十)
URL分享:http://scyanting.com/article/giopgo.html