zoukankan      html  css  js  c++  java
  • 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++编程规范

  • 相关阅读:
    CentOS6.5 [ERROR] /usr/libexec/mysqld: Can't create/write to file '/var/lib/mysqld/mysqld.pid' (Errcode: 2)
    linux防火墙
    Linux磁盘分区与LVM详解
    LVM分区扩展空间
    linux 分区方法(超过2T的硬盘)
    linux异常处理:selinux配置错误导致无法重启
    linux网卡配置文件
    Zabbix4.0系统clone、mass update使用
    Zabbix系统配置日志监控告警--关键字触发
    Zabbix4.0系统配置事件通知
  • 原文地址:https://www.cnblogs.com/alantu2018/p/8471023.html
Copyright © 2011-2022 走看看