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