CS253: Software Development with C++

Fall 2020

Extensible Not Mutable

Show Lecture.ExtensibleNotMutable as a slide show.

CS253 Extensible Not Mutable

Extensible, not mutable

Extending

int main() {
    string sin = "Impeached: ";
    string all = sin + 17 + ' ' + 42 + ' ' + 45;
    cout << all << '\n';
}
c.cc:3: error: no match for 'operator+' in 'sin + 17' (operand types are 
   'std::__cxx11::string' {aka 'std::__cxx11::basic_string<char>'} and 'int')

That failed, because you can’t use + on a std::string and an int.

Extending

string operator+(const string &s, int n) {
    return s + to_string(n);
}

int main() {
    string sin = "Impeached: ";
    string all = sin + 17 + ' ' + 42 + ' ' + 45;
    cout << all << '\n';
}
Impeached: 17 42 45

Hooray! C++ is extensible! I extended the language to include string + int.

For all I know, there’s some obscure (that means something I don’t know) line of the C++ standard that forbids overloading operators with all built-in and std:: operands.

More Extending

class Fraction {
    int top, bot;
  public:
    Fraction(int num, int den) : top(num), bot(den) { }
    double get() const { return top*1.0/bot; }
};

int main() {
    Fraction f(355, 113);
    cout << f << '\n';
}
c.cc:10: error: no match for 'operator<<' in 'std::cout << f' (operand types 
   are 'std::ostream' {aka 'std::basic_ostream<char>'} and 'Fraction')

Of course, that failed. << has no idea what to do with an ostream (output stream) and a Fraction.

More Extending

class Fraction {
    int top, bot;
  public:
    Fraction(int num, int den) : top(num), bot(den) { }
    double get() const { return top*1.0/bot; }
};

ostream & operator<<(ostream &os, const Fraction &f) {
    os << f.get();
    return os;
}

int main() {
    Fraction f(355, 113);
    cout << f << '\n';
}
3.14159

Hooray! I extended the language to include ostream << Fraction. Why the return os in operator<<?

More Extending

class Fraction {
    int top, bot;
  public:
    Fraction(int num, int den) : top(num), bot(den) { }
    double get() const { return top*1.0/bot; }
};

ostream & operator<<(ostream &os, const Fraction &f) {
    return os << f.get();
}

int main() {
    Fraction f(355, 113);
    cout << f << '\n';
}
3.14159

operator<< can simply return the result of <<. Why is operator<< not a method of Fraction?

How operators work

Mutation

Consider this surprising result:

int main() {
    char now[] = "07:36:29";
    cout << now+3 << '\n';
}
36:29

I don’t like this. I want it to simply append a "3" to the string. Let’s redefine it!

Futility

string operator+(char *p, int n) {
    return p + to_string(n);
}

int main() {
    char now[] = "07:36:29";
    cout << now+3 << '\n';
}
c.cc:1: error: ‘std::string operator+(char*, int)’ must have an argument of 
   class or enumerated type

That failed. I can’t mutate the language. char * + int is already defined, and I can’t change it.

Besides, at least one of the arguments has to be a non-built-in type. It wouldn’t work if I tried to define operator%(char *p, int n)