类的静态成员变量及函数(二十)-创新互联

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

让客户满意是我们工作的目标,不断超越客户的期望值来自于我们对这个行业的热爱。我们立志把好的技术通过有效、简单的方式提供给客户,将通过不懈努力成为客户在信息化领域值得信任、有价值的长期合作伙伴,公司提供的服务项目有:域名注册网站空间、营销软件、网站建设、木垒哈萨克网站维护、网站推广。

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

#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。

另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。


分享标题:类的静态成员变量及函数(二十)-创新互联
转载注明:http://ybzwz.com/article/cssjes.html