码迷,mamicode.com
首页 > 编程语言 > 详细

C++ Primer 学习笔记_22_类与数据抽象(8)--static 成员变量、static 成员函数、类/对象的大小

时间:2015-07-31 10:46:32      阅读:145      评论:0      收藏:0      [点我收藏+]

标签:c++ primer   c++   类与数据抽象   

一、static

    每个static数据成员是与类关联的对象,并不与该类的对象相关联非static数据成员存在于类类型的每个对象中,static数据成员独立该类的任意对象存在。

    static成员函数没有this形参,它可以直接访问所属类的static成员,但是不能直接使用static成员

1、static 成员变量

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

(1)、static成员的定义

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

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

        为整型时,有三种情况:第一,可在此处声明,但仍需在类定义体外进行定义初始化,因为const必须初始化。第二,直接在此处进行定义初始化,就不能在类定义体外进行赋值,const不能重复赋值。第三,绝对不允许在构造函数的初始化列表进行初始化。注意:为非整型时,不能在此处初始化,整型包括char、short、long、int(但是我尝试了float,和double在g++还是可以的,所以需要再考证)


【例子】

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成员是与特定类关联的。这种可见性可清晰地显示程序员的意图。

可以通过作用域操作符从类直接调用static成员,或者通过对象引用指向该类类型对象的指针间接调用。static成员遵循正常的公有/私有访问规则

#include <iostream>
using namespace std;

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

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

int CountedObject::GetCount()
{
    return count_;
}

int main(void)
{
    cout << CountedObject::GetCount() << endl;
    CountedObject co1;
    //cout<<CountedObject::count_<<endl; //Error
    cout << co1.GetCount() << endl; //通过对象间接调用
    cout << CountedObject::GetCount() << endl; //通过作用域操作符从类直接调用
    CountedObject *co2 = new CountedObject;
    cout << co2->GetCount() << endl;//通过指向该类类型对象的指针间接调用
    cout << CountedObject::GetCount() << endl;
    delete co2;
    cout << CountedObject::GetCount() << endl;
}
运行结果:
0
1
1
2
2
1
解释:上述程序定义一个静态成员变量和静态成员函数,可以通过类名:: 访问static 成员函数,也可以通过非/静态成员函数访问。


2、static 成员函数

(1)static成员函数没有隐含的this指针,static成员是类的组成部分但不是任何对象的组成部分
(2)非静态成员函数可以访问静态成员
(3)静态成员函数不可以直接访问非静态成员(实际上是直接访问是不可以的,间接地访问是可以的,比如通过类指针或类引用)

(4)因为static成员不是任何对象的组成部分,所以static成员函数不能被声明为 const。毕竟,将成员函数声明为const就是承诺不会修改该函数所属的对象。

(5)最后,static成员函数也不能被声明为虚函数(后面介绍)。


二、类/对象大小计算

(1)类的大小与数据成员有关(空类大小为1个字节)
(2)类的大小与成员函数无关
(3)类的大小与静态数据成员无关
(4)虚函数对类的大小的影响,后续再考虑
(5)虚继承对类的大小的影响,后续再考虑

【例子】
#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;
}
运行结果:
4
解释:上述只与类的数据成员有关,定义了一个int类型,因此,该类大小为4个字节。


参考:

C++ primer 第四版
Effective C++ 3rd

http://blog.csdn.net/zjf280441589/article/details/24838175

http://blog.csdn.net/jnu_simba/article/details/9236565

C++编程规范

版权声明:本文为博主原创文章,未经博主允许不得转载。

C++ Primer 学习笔记_22_类与数据抽象(8)--static 成员变量、static 成员函数、类/对象的大小

标签:c++ primer   c++   类与数据抽象   

原文地址:http://blog.csdn.net/keyyuanxin/article/details/47164755

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!