• static 成员变量、static 成员函数、类/对象的大小


    一、static 成员变量

    对于特定类型的全体对象而言,有时候可能需要访问一个全局的变量。比如说统计某种类型对象已创建的数量。
    如果我们用全局变量会破坏数据的封装,一般的用户代码都可以修改这个全局变量,这时可以用类的静态成员来解决这个问题。
    非static数据成员存在于类类型的每个对象中,static数据成员独立该类的任意对象存在,它是与类关联的对象,不与类对象关联。

    (1)、static成员的定义

    static成员需要在类定义体外进行初始化与定义

    (2)、特殊的整型static const成员

    整型static const成员可以在类定义体中初始化,该成员可以不在类体外进行定义

     C++ Code 
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    class Test
    {
    public:
        Test(): a(0) {}
        enum {size1 = 100, size2 = 200};
    private:
        const int a;   //只能在构造函数初始化列表中初始化
        static int b;    //在类的实现文件中定义并初始化
        const static int c;    //与 static const int c; 相同。
    };

    int Test::b = 0; //static成员变量不能在构造函数初始化列表中初始化,因为它不属于某个对象。
    const int Test::c = 0; //注意:给静态成员变量赋值时,不需要加static修饰符,但要加const

    (3)、static成员优点:

    static成员的名字是在类的作用域中,因此可以避免与其它类成员或全局对象名字冲突。

    可以实施封装,static成员可以是私有的,而全局对象不可以

    阅读程序容易看出static成员与某个类相关联,这种可见性可以清晰地反映程序员的意图。

     C++ Code 
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    #ifndef _COUNTED_OBJECT_H_
    #define _COUNTED_OBJECT_H_

    class CountedObject
    {
    public:
        CountedObject();
        ~CountedObject();
    public:
        static int GetCount();
    private:
        static int count_;      // 静态成员的引用性声明
    };


    #endif // _COUNTED_OBJECT_H_
     C++ Code 
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
    #include "CountedObject.h"

    int CountedObject::count_ = 0;      // 静态成员的定义性声明

    CountedObject::CountedObject()
    {
        ++count_;
    }

    CountedObject::~CountedObject()
    {
        --count_;
    }

    int CountedObject::GetCount()
    {
        return count_;
    }
     C++ Code 
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
    #include "CountedObject.h"
    #include <iostream>
    using namespace std;

    int main(void)
    {
        //cout<<CountedObject::count_<<endl;
        cout << CountedObject::GetCount() << endl;
        CountedObject co1;
        //cout<<CountedObject::count_<<endl;
        cout << CountedObject::GetCount() << endl;
        CountedObject *co2 = new CountedObject;
        //cout<<CountedObject::count_<<endl;
        cout << CountedObject::GetCount() << endl;
        delete co2;
        //cout<<CountedObject::count_<<endl;
        cout << CountedObject::GetCount() << endl;

    }

    上述程序定义一个静态成员变量和静态成员函数,可以通过类名:: 访问static 成员变量,也可以通过非/静态成员函数访问。


    二、static 成员函数

    static成员函数没有隐含的this指针
    非静态成员函数可以访问静态成员
    静态成员函数不可以访问非静态成员(实际上是直接访问是不可以的,间接地访问是可以的,比如通过类指针或类引用)

     C++ Code 
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
     
    #include <iostream>
    using namespace std;

    class Test
    {
    public:
        Test(int y) : y_(y)
        {

        }
        ~Test()
        {

        }

        void TestFun()
        {
            cout << "x=" << x_ << endl; //OK,非静态成员函数可以访问静态成员
            TestStaticFun();
        }
        static void TestStaticFun()
        {
            cout << "TestStaticFun ..." << endl;
            //TestFun();        Error,静态成员函数不能调用非静态成员函数
            //cout<<"y="<<y_<<endl;     Error,静态成员函数不能访问非静态成员
        }
        static int x_;      // 静态成员的引用性说明
        int y_;
    };

    int Test::x_ = 100;     // 静态成员的定义性说明

    int main(void)
    {
        cout << sizeof(Test) << endl;

        return 0;
    }

    三、类/对象大小计算

    类大小计算遵循前面学过的结构体对齐原则(参照这里
    类的大小与数据成员有关与成员函数无关(空类大小为1个字节)
    类的大小与静态数据成员无关
    虚函数对类的大小的影响(参考这里
    虚继承对类的大小的影响(参考这里


    参考:

    C++ primer 第四版
    Effective C++ 3rd
    C++编程规范

  • 相关阅读:
    php 5.3新特性
    php:// — 访问各个输入/输出流(I/O streams)
    php 二维数组排序
    js 面向对象式编程
    jQuery 源码学习笔记
    c++ 指针(二)
    c++ 指针(一)
    visual studio 2012 的制作ActiveX、打包和发布
    用linqPad帮助你快速学习LINQ
    Caliburn.Micro学习笔记(五)----协同IResult
  • 原文地址:https://www.cnblogs.com/alantu2018/p/8471023.html
Copyright © 2020-2023  润新知