The implementation of a member function doesn't have to be as picky as its advertised requirements. Also, a member function can deliver more than the minimum specified by its advertised promises. In the following example, the actual behavior of Fred::f() is different from its advertisement but different in a way that is substitutable and thus won't surprise users. class Fred { public: int f(int i); // REQUIRE: Parameter i must be odd // (if i is odd, this doesn't guarantee to fulfill its // PROMISE) // PROMISE: Return value will be some even number }; int Fred::f(int i) { if (i % 2 == 0) { // This could throw an exception here, but it doesn't // have to } // This is allowed to return any even number, // but it can do something very specific if desired ... return 8; } int main() { Fred fred; int result = fred.f(37); // This is allowed to assume result is even // (but it's not allowed to assume result is 8.) } A specification is said to be adaptable when it is vague enough that an implementation may actually require less than its advertised requirements or when an implementation may actually deliver more than its advertised promises. Adaptable specifications are common in base classes since the adaptability gives extra latitude to derived classes. |