在 C++ 中使用 static 关键字

Jinku Hu 2023年1月30日 2021年6月28日
  1. 在 C++ 中使用 static 关键字声明具有静态持续时间的变量
  2. 使用 static 关键字在 C++ 中声明类的静态成员
在 C++ 中使用 static 关键字

本指南将解释如何在 C++ 中使用 static 关键字的几种方法。

在 C++ 中使用 static 关键字声明具有静态持续时间的变量

static 关键字可用于声明具有静态持续时间的局部变量。与命名可能暗示的相反,具有静态持续时间的局部变量意味着即使在声明变量的块超出范围之后,它的值仍然在内存中保持活动状态。

基本上,这些局部变量可以在定义它们的函数调用之间保存它们的值。请注意,incrementCount 函数有一个名为 count 的变量,它的初始化值为 0count 属性分配在活动的内存区域中,直到程序终止。因此,每次调用 incrementCount 都会向给定的整数添加一个单位。

#include<iostream>

using std::cout;
using std::endl;

int incrementCount()
{
    static int count = 0;
    return ++count;
}

int main() {

    for (int i = 0; i < 20; ++i) {
        if (i % 2 == 0)
            incrementCount();
    }
    cout << incrementCount() - 1 << endl;

    return EXIT_SUCCESS;
}

输出:

10

使用 static 关键字在 C++ 中声明类的静态成员

另一方面,static 关键字用于声明类的静态数据成员。这些成员与类类型本身相关联,而不是与类的特定实例相关联。因此,如果我们为给定类定义静态数据成员,则该类类型的每个实例都将具有相同的数据成员值。与拥有私有成员不同,前者在内存中只有一个副本。从类内存占用的角度来看,后一个特性使静态数据成员高效。

static 数据成员的定义和初始化与常规数据成员不同。static 成员应该在类内声明并在相关源文件中的类外定义。static 关键字仅用于类内的声明。任何 static 数据成员都不能由构造函数初始化,并且它们不能在类体内初始化,除非它们具有 const 整数类型。后一种类型仍然需要在没有初始值规范的情况下在类主体之外定义。下面的示例演示了 static 数据成员 name 的简单用法,它使用字符串文字进行初始化,然后使用 setNewName 函数进行修改。

#include<iostream>
#include<string>
#include <utility>

using std::cout; using std::cin;
using std::endl; using std::string;

class MyClass1 {
private:
    static string name;
    string nickname;
public:
    explicit MyClass1(string n) : nickname(std::move(n)) {};

    static string getName() { return name; }
    static void setNewName(std::basic_string<char> s) { name = std::move(s); }
    string getNickname() { return nickname; }

    ~MyClass1() = default;
};

string MyClass1::name = "Static name";

int main() {
    MyClass1 m1(string("April"));
    MyClass1 m2(string("Maude"));

    cout << MyClass1::getName() << endl;
    MyClass1::setNewName("New name");
    cout << MyClass1::getName() << endl;

    return EXIT_SUCCESS;
}

输出:

Static name
New name

或者,该类可能具有未绑定到任何对象的 static 函数成员,因此它们不能在其主体中引用 this 对象。通常,这些函数不需要像 static 数据成员那样有单独的声明和定义,如下面的示例程序所示。尽管如此,大多数现代风格指南通常会要求程序员将两者解耦。

#include<iostream>
#include<string>
#include <utility>

using std::cout; using std::cin;
using std::endl; using std::string;

class MyClass1 {
private:
    static string name;
    string nickname;
public:
    explicit MyClass1(string n) : nickname(std::move(n)) {};

    static string getName() { return name; }
    static void setNewName(std::basic_string<char> s) { name = std::move(s); }
    string getNickname() { return nickname; }

    static bool compareStrings(const std::basic_string<char>& s1,
                               const std::basic_string<char>& s2) {
        if (s1 == s2)
            return true;
        else
            return false;
    }

    ~MyClass1() = default;
};

string MyClass1::name = "Static name";

int main() {

    MyClass1 m1(string("April"));
    MyClass1 m2(string("Maude"));

    MyClass1::compareStrings(m1.getNickname(), m2.getNickname()) ?
                cout << "strings are equal" << endl :
                cout << "strings are not equal" << endl;


    MyClass1::compareStrings(MyClass1::getName(), MyClass1::getName()) ?
                cout << "strings are equal" << endl :
                cout << "strings are not equal" << endl;


    return EXIT_SUCCESS;
}

输出:

strings are not equal
strings are equal
Author: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn

相关文章 - C++ Static