Funkcje składowe klasy mogą być zadeklarowane jako statyczne. Takie funkcje można wywołać nawet wtedy, gdy nie istnieje jeszcze żaden obiekt klasy. Do ich nazwy z zewnątrz klasy odwołujemy się poprzez nazwę klasy za pomocą operatora zasięgu, czyli „czterokropka” (' ::'), albo za pomocą operatora wyboru składowej (kropka) — nie ma wtedy znaczenia, jakiego obiektu tej klasy użyjemy. Ponieważ funkcja statyczna nie jest wywoływana na rzecz obiektu, ale jak funkcja globalna, nie można w niej odwoływać się do this ani do żadnych składowych niestatycznych — te bowiem istnieją tylko wewnątrz konkretnych obiektów i w każdym z nich mogą być różne. Można natomiast w funkcjach statycznych klasy odwoływać się do składowych statycznych tej klasy: innych funkcji statycznych i zmiennych klasowych (określanych przez statyczne pola klasy).
Funkcje statyczne klasy od funkcji zadeklarowanych w zasięgu globalnym różni to, że należą do zakresu (przestrzeni nazw) klasy. Mają zatem bezpośredni dostęp do nazw z zakresu tej klasy (również prywatnych).
Na przykład program
acc.cpp może być przepisany
w następujący sposób, tym razem z funkcją obliczającą iloczyn
skalarny jako funkcją statyczną:
1. #include <iostream>
2. using namespace std;
3.
4. class Vector {
5. double x, y, z;
6. public:
7. void set(double xx = 0, double yy = 0, double zz =0) {
8. x = xx;
9. y = yy;
10. z = zz;
11. }
12. static double dot_product(const Vector& w1,
13. const Vector& w2) {
14. return w1.x * w2.x + w1.y * w2.y + w1.z * w2.z;
15. }
16. };
17.
18. int main() {
19. Vector w1, w2, ww;
20. w1.set(1, 1, 2);
21. w2.set(1,-1, 2);
22.
23. cout << "w1*w2 = "
24. << Vector::dot_product(w1, w2) << endl; ➊
25.
26. cout << "w1*w2 = "
27. << ww.dot_product(w1, w2) << endl; ➋
28. }
Zauważmy wywołanie z linii ➊ poprzez kwalifikację nazwą klasy i wywołanie z linii ➋, gdzie funkcja jest wywoływana formalnie na rzecz obiektu ww, choć w rzeczywistości żadna informacja o tym obiekcie nie zostanie do funkcji przekazana (nie był on nawet sensownie zainicjowany!). Obiekt ww został użyty wyłącznie do tego, aby określić klasę w której zasięgu określona jest nazwa funkcji; równie dobrze mogliśmy tu użyć dowolnego innego obiektu klasy Vector. Cała informacja o wektorach które mają być pomnożone jest przekazywana przez argumenty.
T.R. Werner, 21 lutego 2016; 20:17