在 C++ 中使用 static 關鍵字

Jinku Hu 2023年10月12日
  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::cin;
using std::cout;
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::cin;
using std::cout;
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
作者: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

DelftStack.com 創辦人。Jinku 在機器人和汽車行業工作了8多年。他在自動測試、遠端測試及從耐久性測試中創建報告時磨練了自己的程式設計技能。他擁有電氣/ 電子工程背景,但他也擴展了自己的興趣到嵌入式電子、嵌入式程式設計以及前端和後端程式設計。

LinkedIn Facebook

相關文章 - C++ Static