In this chapter, you learned how to build more robust classes by defining overloaded operators that enable programmers to treat objects of your classes as if they were fundamental C++ data types. We presented the basic concepts of operator overloading, as well as several restrictions that the C++ standard places on overloaded operators. You learned reasons for implementing overloaded operators as member functions or as global functions. We discussed the differences between overloading unary and binary operators as member functions and global functions. With global functions, we showed how to enable objects of our classes to be input and output using the overloaded stream extraction and stream insertion operators, respectively. We showed a special syntax that is required to differentiate between the prefix and postfix versions of the increment (++) operator. We also demonstrated standard C++ class string, which makes extensive use of overloaded operators to create a robust, reusable class that can replace C-style, pointer-based strings. Finally, you learned how to use keyword explicit to prevent the compiler from using a single-argument constructor to perform implicit conversions. In the next chapter, we continue our discussion of classes by introducing a form of software reuse called inheritance. We will see that classes often share common attributes and behaviors. In such cases, it is possible to define those attributes and behaviors in a common "base" class and "inherit" those capabilities into new class definitions.