C++ 入门07:静态成员和常量成员

往期回顾:

C++ 入门04:数组与字符串-CSDN博客

C++ 入门05:类和对象-CSDN博客

C++ 入门06:类的进阶(构造函数的重载与拷贝构造函数)-CSDN博客


 一、前言

在前面文章的学习中,我们掌握了类和对象的基础知识以及构造函数的重载与拷贝构造函数。今天,我们将学习类的静态成员和常量成员。静态成员和常量成员是面向对象编程中重要的概念,了解它们有助于我们编写更高效和更安全的代码。

二、静态成员和常量成员

2.1、静态成员

静态成员,作为面向对象编程中的一个重要概念,是定义在类级别上而非实例级别上的。这意味着它们不依赖于类的任何特定对象实例,而是属于类本身。静态成员主要包括静态变量(或称为类变量)和静态函数(或称为类方法)。这些成员提供了一种机制,允许在类的所有实例之间共享数据和功能。

(1)静态成员变量

静态成员变量是那些被类的所有实例共享的变量。这意味着,无论创建了多少个类的实例,静态变量都只有一份拷贝。这些变量在内存中只有一个存储空间,由所有实例共同访问和修改(如果允许的话)。静态成员变量特别适用于存储那些与类本身相关,但与特定实例无关的数据。

A、特性
  1. 共享性:所有对象实例共享同一个静态成员变量的值。
  2. 初始化:静态成员变量在程序开始执行时(或在第一次被访问前,具体取决于编译器的实现)只初始化一次。
  3. 访问性:可以通过类名直接访问静态成员变量,也可以通过类的实例访问。
B、声明和定义

在C++或类似的语言中,静态成员变量的声明通常放在类的定义中,使用static关键字标识。然而,由于静态成员变量属于类而非类的任何特定对象,因此它们不能在类的定义中直接初始化(除非使用了常量表达式进行初始化,这种情况称为就地初始化)。相反,静态成员变量的定义(包括其初始化)必须在类的定义外部进行,并且只能进行一次。这通常是通过在类的实现文件中指定其类型和名称,并可能包含初始化表达式来完成的。

// 类的定义  
class MyClass {  
public:  
    static int staticVar; // 声明静态成员变量  
    // ... 其他成员 ...  
};  
  
// 静态成员变量的定义(包括初始化)  
int MyClass::staticVar = 0; // 在类外部定义并初始化静态成员变量

注意:如果静态成员变量是const整型或枚举类型,并且使用常量表达式进行初始化,那么它可以在类定义内部直接初始化,而无需在类外部进行定义。

静态成员变量的这种特性使得它们成为存储类级别数据(如计数器,用于跟踪已创建的实例数量)的理想选择。

示例:

#include <iostream>
using namespace std;

class Car {
public:
    string brand;
    string model;
    int year;
    static int carCount; // 声明静态成员变量

    Car(string b, string m, int y) {
        brand = b;
        model = m;
        year = y;
        carCount++; // 每创建一个对象,carCount 加 1
    }

    void displayInfo() {
        cout << "Brand: " << brand << endl;
        cout << "Model: " << model << endl;
        cout << "Year: " << year << endl;
    }
};

// 在类外部定义静态成员变量
int Car::carCount = 0;

int main() {
    Car car1("Toyota", "Corolla", 2020);
    Car car2("Honda", "Civic", 2019);

    cout << "Total cars: " << Car::carCount << endl; // 访问静态成员变量

    return 0;
}

在这个示例中,carCount 是一个静态成员变量,它在所有 Car 对象之间共享。每次创建一个 Car 对象,carCount 的值就会增加。

(2)静态成员函数

静态成员函数是定义在类级别上的一种特殊成员函数,它们与类本身相关联,而不是与类的某个特定对象实例相关联。这意味着,静态成员函数可以在没有创建类对象的情况下被调用,它们通过类名直接访问,而不是通过类的实例对象。

A、静态成员函数的特点
  1. 属于类而非对象:静态成员函数是类的组成部分,而不是任何特定对象的成员。因此,它们不依赖于类的实例变量,也不具有this指针(在C++中)。

  2. 访问限制:静态成员函数只能直接访问类的静态成员变量和静态成员函数。这是因为非静态成员变量和成员函数是特定于对象的,而静态成员函数在调用时并不绑定到任何特定的对象实例。

  3. 调用方式:静态成员函数可以通过类名直接调用,也可以通过类的实例对象调用(尽管这种调用方式在逻辑上并不常见,因为它违背了静态成员函数的初衷)。

B、静态成员函数与非静态成员的访问

由于静态成员函数不依赖于任何特定的对象实例,因此它们不能直接访问类的非静态成员变量和非静态成员函数。非静态成员是特定于对象的,它们的值或行为可能因对象的不同而有所差异。静态成员函数在调用时并不自动与任何对象实例相关联,因此没有途径来访问或修改非静态成员。

如果静态成员函数需要访问非静态成员,那么它必须显式地通过某个对象实例来调用这些成员。这通常是通过将对象实例作为参数传递给静态成员函数来实现的,但这会破坏静态成员函数的初衷,因为它将静态成员函数的调用与特定的对象实例绑定在一起。

语法:

class ClassName {
public:
    static 返回类型 静态成员函数名(参数列表);
};

示例:

#include <iostream>
using namespace std;

class Car {
public:
    string brand;
    string model;
    int year;
    static int carCount;

    Car(string b, string m, int y) {
        brand = b;
        model = m;
        year = y;
        carCount++;
    }

    static int getCarCount() { // 静态成员函数
        return carCount;
    }

    void displayInfo() {
        cout << "Brand: " << brand << endl;
        cout << "Model: " << model << endl;
        cout << "Year: " << year << endl;
    }
};

int Car::carCount = 0;

int main() {
    Car car1("Toyota", "Corolla", 2020);
    Car car2("Honda", "Civic", 2019);

    cout << "Total cars: " << Car::getCarCount() << endl; // 调用静态成员函数

    return 0;
}

在这个示例中,getCarCount 是一个静态成员函数,用于返回 carCount 的值。静态成员函数只能访问静态成员变量。

2.2、 常量成员

 常量成员是面向对象编程中一个重要的概念,用于确保类的某些成员在创建后保持不变,即它们的值或行为在对象的整个生命周期内都是恒定的。在类中,常量成员可以包括常量成员变量(也称为常量属性)和常量成员函数(也称为常量成员函数或只读成员函数)。这里,我们主要扩写常量成员变量的相关内容。

(1)常量成员变量

常量成员变量是通过在成员变量声明前加上const关键字来定义的。这个const修饰符表明该成员变量的值在对象被创建之后就不能被修改。常量成员变量提供了一种机制,用于在类的设计中嵌入那些不应该被改变的值,从而增加了代码的健壮性和可维护性。

A、特性:
  1. 初始化要求:常量成员变量必须在对象创建时被初始化。这可以通过在类的构造函数初始化列表中指定初始值来完成,而不能在类的声明中直接初始化(除非使用了C++11及以后版本中的就地初始化功能,但这通常不适用于常量成员变量,因为它要求使用常量表达式)。

  2. 不可变性:一旦常量成员变量被初始化,它的值就不能在对象的生命周期内被修改。这意呀着,任何尝试修改常量成员变量的操作都将导致编译错误。

  3. 访问控制:常量成员变量的访问控制(如publicprotectedprivate)与普通成员变量相同,但它们的不可变性是全局的,不受访问控制符的影响。

语法:

class ClassName {
public:
    const 数据类型 常量成员变量名;
    ClassName(参数列表) : 常量成员变量名(初始值) {}
};

示例:

#include <iostream>
using namespace std;

class Car {
public:
    const int maxSpeed; // 常量成员变量
    string brand;
    string model;
    int year;

    Car(string b, string m, int y, int ms) : maxSpeed(ms) {
        brand = b;
        model = m;
        year = y;
    }

    void displayInfo() {
        cout << "Brand: " << brand << endl;
        cout << "Model: " << model << endl;
        cout << "Year: " << year << endl;
        cout << "Max Speed: " << maxSpeed << " km/h" << endl;
    }
};

int main() {
    Car car1("Toyota", "Corolla", 2020, 180);
    car1.displayInfo();

    return 0;
}

在这个示例中,maxSpeed 是一个常量成员变量,它在构造函数中初始化,并且在对象的生命周期内不能修改。

(2)常量成员函数

常量成员函数在定义时加上 const 关键字,表示该函数不会修改对象的任何成员变量。

语法:

class ClassName {
public:
    返回类型 成员函数名(参数列表) const;
};

示例:

#include <iostream>
using namespace std;

class Car {
public:
    string brand;
    string model;
    int year;

    Car(string b, string m, int y) {
        brand = b;
        model = m;
        year = y;
    }

    void displayInfo() const { // 常量成员函数
        cout << "Brand: " << brand << endl;
        cout << "Model: " << model << endl;
        cout << "Year: " << year << endl;
    }
};

int main() {
    Car car1("Toyota", "Corolla", 2020);
    car1.displayInfo();

    return 0;
}

 在这个示例中,displayInfo 是一个常量成员函数,表示该函数不会修改 Car 对象的任何成员变量。


以上就是 C++ 程序的静态成员和常量成员的基础知识点了。静态成员属于类而不是对象,常量成员在对象的生命周期内不能修改。

都看到这里了,点个赞再走呗朋友~

加油吧,预祝大家变得更强!

  • 19
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值