C++ Primer 第七章⑥

C++ Primer

第七章 类

类的静态成员

我们目前学到的类的内容都是实例化后每个对象各自拥有的,有时候,有时候,类需要它的一些成员与类本身直接相关。例如,一个银行账户类可能需要一个数据成员来表示当前的基准利率,我们希望利率与类关联,而不是和对象关联,更加重要的是,一旦利率变化,我们希望所有的对象都能使用新值

声明静态成员

我们就来写个银行账户类:

class Account
{
public:
    void calculate()
    {
        amaunt += amount * intereatRate;
    }
    static double rate(){return interestRate;}
    static void rate(double);

private:
    string owner;
    double amount;
    static double interestRate;
    static double initRate();
};

类的静态成员存在于对象之外,所以啊,每个Account对象只有两个数据成员:owner和amount,而interestRate是类所有,所有对象共享。 因为静态成员函数不与任何对象绑定,所以没有this指针,不能声明为const的。

使用类的静态成员

使用类作用域运算符::直接访问:

double r;
r = Account::rate();

我们还是可以用对象去访问静态成员,毕竟共享

Account c1;
Account *ac2 = &ac1;
r = ac1.rate();
r = ac2->rate();

以上是在类外访问,如果在类内呢?你看上面的calculate函数就知道了,直接访问。

定义静态成员

突然想起个小问题:类成员函数的声明只能放在类内,对不?(对的,求讨论)
类内部定义前面的代码已经有了,就是加个关键字static;在类外部定义静态成员时,不能重复static关键字,该关键字只能出现在类内部的声明语句。

因为类的静态数据成员不属于任何一个对象,所以它们不是在实例化时被定义的,也就是说,构造函数不负责初始化它们,而且一般来说,我们要在类的外部定义和初始化每一个静态成员。

类似全局变量,静态数据成员定义在任何函数之外,它一旦被定义,就一直存在于程序的整个生命周期中。

我们来定义一个在类内已经声明的static成员:

double Account::interestRate = initRate();
//为什么不用在initRate函数前面加Account::呢
//因为从类名开始,剩下的部分都处于类的作用域之内了。

静态成员的类内初始化

刚刚说过,类的静态成员应该在类外定义初始化,于是C++又来破坏自己定的规矩了:我们可以为静态成员提供const整数类型的类内初始值,不过要求静态成员必须是constexpr的:

class Account
{
public:
    static double rate(){return interestRate;}
    static void rate(double);

private:
    static constexpr int period = 30;
    double daily_tbl[period];
};

为什么这儿要把初始化放在类内呢?因为period的唯一用途就是去定义daily_tbl的维度,那我们就直接在类内定义一下,外面反正不用。值得注意的是,在外面还是要定义一下,相当于声明一下:

constexpr int Account::period; //不带初始值的定义,

我的总结就是,什么狗屁东西,食之无味弃之可惜。

静态成员能用于某些场景,而普通成员不能

class Bar
{
    private:
        static Bar m1; //这个逆天吧,可以自己的类型
        statuc int &m2; //逆天吧,未初始化的引用
};

主要是因为,静态成员一般在外面定义初始化,所以,在类内可以是不完全类型,胡作非为。

还有一个区别是,静态成员可以作为默认实参,666

class Screen
{
public:
    Screen& clear(char = bkground); //666
private:
    static const char bkground; 
};

非静态数据成员不能作为默认实参,因为它是属于对象的,你用对象的值去作为默认实参,结果是无法真正提供一个对象来获取成员的值,会引发错误。

彩蛋

小结:

  • 类允许我们为自己的应用特制类型
  • 类有两项基本能力:
    1. 数据抽象,就是定义数据成员和函数成员
    2. 封装,保护类的成员不被随意访问(private,友元等)
  • 构造函数来控制初始化对象的方式
  • 静态成员与类绑定,存在于对象之外,是所有对象来共享的。
#C++工程师#
全部评论

相关推荐

尊尼获获:闺蜜在哪?
点赞 评论 收藏
分享
7 2 评论
分享
牛客网
牛客企业服务