Usa la parola chiave statica in C++

Jinku Hu 12 ottobre 2023
  1. Usa la parola chiave static per dichiarare variabili con durata statica in C++
  2. Usa la parola chiave static per dichiarare i membri statici della classe in C++
Usa la parola chiave statica in C++

Questa guida spiegherà diversi metodi su come utilizzare la parola chiave static in C++.

Usa la parola chiave static per dichiarare variabili con durata statica in C++

La parola chiave static può essere utilizzata per dichiarare variabili locali con durata statica. Contrariamente a quanto potrebbe suggerire la denominazione, una variabile locale con durata statica implica che il suo valore rimanga attivo in memoria anche dopo che il blocco, in cui è dichiarata la variabile, esce dallo scope.

Fondamentalmente, queste variabili locali possono avere i loro valori salvati tra le chiamate di funzione in cui sono definite. Si noti che la funzione incrementCount ha una variabile chiamata count, che viene inizializzata con il valore 0. L’attributo count è allocato nella regione di memoria attiva fino al termine del programma. Pertanto, ogni chiamata a incrementCount aggiunge una singola unità all’intero dato.

#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;
}

Produzione:

10

Usa la parola chiave static per dichiarare i membri statici della classe in C++

D’altra parte, la parola chiave static viene utilizzata per dichiarare i membri di dati statici della classe. Questi membri sono associati al tipo di classe stesso piuttosto che alle istanze particolari della classe. Quindi, se definiamo un membro dati statico per una data classe, ogni istanza di questo tipo di classe avrà lo stesso valore per il membro dati. A differenza di un membro privato, il primo avrà una sola copia in memoria. Quest’ultima caratteristica rende i membri di dati statici efficienti dal punto di vista dell’impronta di memoria della classe.

I membri dati static sono definiti e inizializzati in modo diverso rispetto ai membri dati normali. I membri static dovrebbero essere dichiarati all’interno della classe e definiti all’esterno della classe nel file sorgente associato. La parola chiave static viene utilizzata solo nella dichiarazione all’interno della classe. Nessuno dei membri dati static può essere inizializzato dai costruttori e non possono essere inizializzati all’interno del corpo della classe a meno che non abbiano un tipo integrale const. Questi ultimi tipi devono ancora essere definiti al di fuori del corpo della classe senza una specifica del valore iniziale. L’esempio seguente mostra il semplice utilizzo del membro dati static name, che viene inizializzato con la stringa letterale e successivamente modificato con la funzione 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;
}

Produzione:

Static name New name

In alternativa, la classe può avere i membri della funzione static che non sono legati ad alcun oggetto, e quindi non possono fare riferimento all’oggetto this nei loro corpi. In genere, queste funzioni non necessitano di dichiarazioni e definizioni separate simili ai membri dati static, come mostrato nel seguente programma di esempio. Tuttavia, la maggior parte delle guide di stile contemporaneo di solito richiede al programmatore di disaccoppiare i due.

#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;
}

Produzione:

strings are not equal strings are equal
Autore: 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 Facebook