Week 7 Lecture Summary for CSC 309
These notes are not intended to be complete. They serve as an outline to the class and as a supplement to the text.
C++ String Class
- Three categories of Strings that C++ programmers deal with.
- C-Style Strings
- Standard Library String Class.
- Third Party Vendors
- C++ strings are objects.
- The C++
string
type provides a high level interface for interacting with the string. #include <string>.
notice lower case 's'.- Part of the
namespace
std
Constructing strings
string s1; // s1 initialized to the empty string. string s2(s1); // Initialize s2 as copy of s1. string s3 = s2; // Same as s2. string s4("windy"); // Initialize s4 with a copy of the string literal. string s5(75,'*'); // Initialize the first 75 characters to *. string s6 = "today is windy";
Input and Output
cin >> s1; // skip leading whitespace, read until whitespace is encountered. cout << s1; // send s1 to output stream. getline(cin, s1); // read the entire line.
getline
does not skip leading whitespaces. Discards newline character and returns its first argument
while( getline(cin, s1) ) { cout << s1 << endl; }
Some Member Functions
s1.empty(); // returns true if s1 is empty, false otherwise. s1.size(); // returns number of characters in the string s1.append("day"); // append "day" to s1. Returns s1. s1.substr(pos,n); // return a stringn
characters, starting atpos
s1.substr(pos); // return a string starting at pos to the end. s1.substr(); // returns a copy of s1. s1.find("w"); // returns the position of the first occurrence of "w" in s1.
Some Overloaded Operators
s1 == s2; // returns true, if s1 and s2 have the same characters, else false s1 < s2; // returns true, if s1 comes before s2. <= > >= != // are all overloaded. s1[2] // returns the character at position n, position starts at 0. s3 = s1 + s2; // returns a new string that concatenates s1 and s2. s1 += s2; // appends s2 to the end of s1.
Dictionary Program
Write a program that gets an English word from the user and outputs the corresponding word(s) in spanish
The following file contains a mapping of English words to Spanish words.
Two user defined classes will be used in solving this problem. Their relationship is depicted as follows.
![]()
Operator Overloading
- Goal to make user defined types to behave like built in types.
- C++ allows you to define operators such as,
+ - * / == != << etc..
to work on operands of class types.
- Overloaded operators are just functions with special names.
- Use keyword
operator
followed by the operator that is to be defined. - To overload the plus operator ( + ) the name of the function would be.
operator+
Example
Recall the Complex class had a method called plus
to add two complex numbers.
Complex c1(2.3,3.2), c2(2,1), c3; c3 = c1.plus(c2); cout << c3.toString() << endl; // output 4.3 + 4.2i
class Complex { private: double real; double imag; public: : : Complex operator+(const Complex & operand2) const; };
Complex Complex::operator+(const Complex & operand2) const{ return Complex(getReal() + operand2.getReal(), getImag() + operand2.getImag()); }
Complex c1(2.3,3.2), c2(2,1), c3; c3 = c1 + c2; cout << c3.toString() << endl; // output 4.3 + 4.2i
The compiler translates the above use of the operator to a method call.
c1.operator+(c2);
c3 = c1 + 4; cout << c3.toString() << endl; // output 6.3 + 3.2i
This works because the Complex class defines a convert constructor.
The compiler will convert the 4 into a temporary Complex object.
Convert Constructor
Complex(double r) : real(r), imag(0.0) {}
c3 = 4 + c1; // error
The above is an error because operator+
is a member function, the object c1
needs to be on the left hand side. The compiler translates the above use of the operator to a method call, in this case to
4.operator(c1);
This doesn't make sense because built in type int would have no clue about a Complex class written by you.
SolutionReplace member function
operator+
with a global function. Here is the declaration and definition.
Complex operator+(const Complex & operand1, const Complex & operand2); Complex operator+(const Complex & operand1, const Complex & operand2) { return Complex(operand1.getReal() + operand2.getReal(), operand1.getImag() + operand2.getImag()); }
Exercise
Overload the equality operator ( == ) for the Complex class. When overloading equality it's expected that the not equal ( != ) operator is available.
bool operator==(const Complex & operand1, const Complex & operand2){ return (operand1.getReal() == operand2.getReal()) && (operand1.getImag() == operand2.getImag()); } bool operator!=(const Complex & operand1, const Complex & operand2){ return !(operand1 == operand2); }
Rules and Guidelines
- Many operators have no meaning for objects. Cannot compare Complex numbers, so no need to overload the relational operators ( < etc ..).
- Symmetric operators (arithmetic, equality and relational) should be defined as global functions.
- Input ( >> ) and Output ( << ) in order to be consistent with the IO library, must be global functions.
- The assignment ( = ), subscript ( [ ] ), call ( () ), and the indirection ( -> ) operators must be defined as member functions. If not, compile time error
- Operators that change the state of the calling object like increment (++) , should be member functions.
- Cannot change the precedence and associativity of an operator.
- Cannot overload built-in types.
- Can overload all operators except the following.
Operator | Purpose |
---|---|
. | Member operator |
.* | Member dereference operator |
:: | Scope resolution operator |
? : | Conditional operator operator |
sizeof | Size in bytes |
Friend Functions
- Sometimes its convenient to let non-member functions access the private members of a class.
- Declaring a method in the class using the keyword friend allows a non-member function access to private members.
- Friends are not members of the class, hence may appear anywhere in the class definition.
- Friend functions violate the principle of information hiding, and if used should be used sparingly.
Example
To allow the definition of the overloaded plus ( + ) operator access to the real and imaginary parts we could make the function a friend of the Complex class.
class Complex { private: double real; double imag; : : public: friend Complex operator+(const Complex & operand1, const Complex & operand2); };
Now the definition could look like.
Complex operator+(const Complex & operand1, const Complex & operand2) { return Complex(operand1.real + operand2.real, operand1.imag + operand2.imag); }
Overloading Input and Output Operators.
- Must be non-member global functions.
- For convenience typically made friends.
- Both must take as first parameter a reference to the stream.
- Both must have a second parameter which is the object.
- Both must return a reference to the stream.
- To overload the input and output operators to work on Complex objects the class definition would look like.
class Complex { private: double real; double imag; public: : : friend istream& operator>>(istream& is, Complex & obj); friend ostream& operator<<(ostream& os, const Complex & obj); };
- Those operators could be used as follows.
- The use of the input operator translates into.
cout << "Enter real and imaginary parts" << endl; cin >> c3; // suppose you input 50 60 cout << c3 << endl; // output 50 + 60i
operator>>(cin, c3);
operator<<(cout, c3); operator<<(cout, endl);
istream& operator>>(istream& is, Complex & obj) { is >> obj.real >> obj.imag; return is; } ostream& operator<<(ostream& os, const Complex & obj) { os << obj.real << " + " << obj.imag << "i"; return os; }
Overloading the Index Operator
- Must be overloaded as a member function
- A class used to keep track of the frequency of integers in the range 1- 10.
Test Code
IntCount count; ++count[65]; ++count[2]; ++count[4]; ++count[4]; ++count[9]; cout << endl << count << endl;
Overloading Operators for Class IntLinkedList
== returns true if two lists are equal, identical elements != returns true if two list are not equal << outputs the list. >> adds an integer to the back of the list.