Static member functions are like services attached to the factory rather than services attached to the objects produced by the factory. #include <cstdlib> #include <iostream> using namespace std; class Car { public: Car() throw(); Car(const Car& c) throw(); // No need for an explicit assignment operator or destructor // since these don't create new Car objects. static int num() throw(); <-- 1 int odometer() const throw(); <-- 2 void drive() throw(); <-- 3 private: static int num_; <-- 4 int miles_; <-- 5 }; Car::Car() throw() : miles_(0) { cout << "Car ctor\n"; ++num_; } Car::Car(const Car& c) throw() : miles_(c.miles_) { cout << "Car copy\n"; ++num_; } int Car::num() throw() <-- 6 { return num_; } int Car::odometer() const throw() { return miles_; } void Car::drive() throw() { ++miles_; } int Car::num_ = 0; <-- 7
Some services make sense only when applied to an object. void fiddleWithObject(Car& car) throw() { while (rand() % 10 != 0) car.drive(); cout << "car.odometer() = " << car.odometer() << '\n'; } Some services make sense only when applied to the factory. void fiddleWithClass() throw() { cout << "Car::num() returns " << Car::num() << '\n'; #ifdef GENERATE_ERROR Car::drive(); <-- 1 Car::odometer(); <-- 2 #endif }
Since the factory exists before it produces its first object, the factory can provide services before instantiating an object. That is, fiddleWithClass() can be called before the first Car object is created and/or after the last Car object is destructed: int main() { fiddleWithClass(); { Car a; fiddleWithClass(); fiddleWithObject(a); } fiddleWithClass(); } |