A static method belongs to the class rather than an object. It can use class-level state but cannot read instance values, so no object is required to call it. section 9.11
Mistake: leaving object-independent helpers as instance methods. In a Rational class, gcd and reduce appear to require an object even though their work can operate on supplied values, reducing readability. section 9.11
Prefer the form that matches what the method needs:
- Declare gcd and reduce static when they use only parameters and class-level information. section 9.11
- Keep a method non-static when it directly changes or reads the current object's state. section 9.11
- Use a free function when placing the helper inside the class adds no clarity. section 9.11
Listing 9.28 Rational reworked to include two class methods
class Rational {
private:
int num;
int den;
static int gcd(int a, int b) { #1
if (b == 0)
return a;
return gcd(b, a % b);
}
static void reduce(int& num, int& den) { #2
int div = gcd(num, den);
num /= div;
den /= div;
}
public:
Rational(int num, int den = 1) : num(num), den(den) {
reduce(this->num, this->den); }
friend std::ostream& operator<<(std::ostream&, const Rational&);
Rational& operator*=(const Rational&);
};
std::ostream& operator<<(std::ostream& out, const Rational& r) {
out << r.num << '/' << r.den;
return out;
}
Rational& Rational::operator*=(const Rational& o) {
num *= o.num;
den *= o.den;
reduce(num, den);
return *this;
}
int main() {
Rational r1(3, 9);
std::cout << r1 << '\n';
return 0;
}
Compare the initial Rational implementation with a refactoring that makes gcd and reduce static and passes numerator and denominator explicitly. section 9.11




