C++ 类中的静态成员

为什么要有类的静态成员?

我们学习一个知识点,首先想到的是为什么要有这个东西的存在呢?对于C++ 类的静态成员存在的理由如下:
有的时候类需要它的一些成员与类本身无关,而不是与类的各个对象保持关联。

例如:一个银行账户类型类可能需要一个数据成员来表示当前基准利率。在此例中,我们希望利率与类关联,而非与类的每个对象关联。从实现的效率的角度来看,没必要每个对象都存储利率信息。而且更加重要的是,一旦利率浮动,我们希望所有的对象都能使用新的利率值。

  1. 声明静态成员:

通常在成员的声明之前加上 static 关键字,使得静态成员与类关联起来。和其它成员一样,静态成员可以是 public 或者 private。静态数据成员的类型可以是常量、引用、指针、类类型。

class Account{
public:
     void calculate(){
         amount += amount * interestRate;
     }

     static double rate(){
         return interestRate;
     }

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

类的静态成员存在于任何对象之外,对象中不包括任何与静态数据成员有关的数据。因此,每个Account 对象将包含两个数据成员:owner 和 amount。只存在一个 interestRate 对象而且它被所有 Amount 对象共享。

类似的,静态成员函数不与任何对象绑定在一起,它们不包含 this 指针。作为结果,静态成员函数不能声明成 const 的,而且我们也不能在 static 函数体内使用 this 指针。

  1. 使用类的静态成员

我们使用作用域运算符直接访问静态成员:

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

虽然静态成员不属于类的某个对相关,但是我们仍然可以使用类的对象、引用、指针来访问静态成员。成员函数不用通过作用域运算符就能直接使用静态成员。

  1. 定义静态成员

和其它的成员函数一样,我们既可以在类的内部也可以在类的外部定义静态成员函数。当在类的外部定义静态成员时,不能重复 static 关键字,该关键字只能出现在类内部的声明语句:

void Account : : rate(double newRate){
        interestRate = newRate;
}

因为静态数据成员不属于类的任何一个对象,所以它们并不是创建类的对象时被定义的。这意味着它们不是由类的构造函数初始化的。而且一般来说,我们不能在类的内部初始化静态成员。相反的,必须在类的外部定义和初始化每个静态成员。和其它对象一样,一个静态数据成员只能定义一次。

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

我们定义静态数据成员方式如下:(我们需要指定对象的类型名,然后是类名,作用域运算符以及成员自己的名字)

double Account : : interestRate = initRate();
  1. 静态成员的类内初始化

通常情况下,类的静态成员不应该在类的内部初始化。然而,我们可以为静态成员提供 const 整型类型的类内初始化,不过要求静态成员必须是字面值常量类型的 constexpr。初始值必须是常量表达式,因为这些成员本身就是常量表达式,所以它们就能用所有适合于常量表达式的地方。

  1. 静态成员使用的场景

  • 静态成员可以是不完全类型。特别的,静态数据成员的类型可以就是它所属的类类型。而非静态成员则受限,只能声明成所属类的指针或者引用。
  • 静态成员和普通成员的另外一个区别就是我们可以使用静态成员作为默认实参。非静态成员不能作为默认实参,因为它的值本身属于对象的一部分。
练习面试题:

斐波那契数列:
当使用正常的递归解题时,时间复杂度过高,所以我们可以使用静态成员函数解题:

class Solution {
public:
    int Fibonacci(int n) {
        return Fibonacci(n, 0, 1);
    }
    
private: 
    static int Fibonacci(int n,int acc1,int acc2){
        if(n==0) return 0;
        if(n==1) return acc2;
        else     return Fibonacci(n - 1, acc2, acc1 + acc2);
    }
};
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值