-
The class Money has two data members: dollars and
cents. A function that overloads
operator+ that adds two Money values and returns a
Money value representing their sum is to be written. If
this function is declared in the Money class at (*) below,
which of the declarations shown would be correct?
class Money
{
int dollars;
int cents;
public:
Money();
Money(int d, int c);
// (*) Declare an overloaded operator+
...
};
(1) Money operator+(const Money& m) const;
(2) Money operator+(const Money& m1, const Money& m2);
(3) friend Money operator+(const Money& m1, const Money& m2);
(4) friend Money operator+(const Money& m1, const Money& m2) const;
- Any one of these would be correct
- Only (1)
- Only (2)
- Only (1) or (3)
- Only (2) or (3)
- Only (1) or (4)
- Only (2) or (4)
Here is the design outut for one of the classes:
Invoice.h
(What data members are needed?)
class Invoice
{
public:
/**
* Initialize an Invoice for up to maxItems LineItems
*/
Invoice();
Invoice(int maxItems);
Invoice(const Address& addr, int maxItems);
/**
* Formats the invoice
*/
string format();
/**
* Adds a line item for a product and quantity to
* this invoice.
*/
void add(const Product& p, int quantity);
};
class LineItem
{
public:
/**
* Initialize LineItem
*/
LineItem();
LineItem(const Product& p, int quantity);
/**
* format the line item
*/
string format();
/**
* get line item total amount
*/
double getLineTotal();
};
To implement the design:
- Each design class must add data members.
- Each constructor and member function must be implemented.
In addition, we must provide tests for the class(es).
Here is a sample invoice test program:
int main()
{
Address ezAddr("EZ Rental",
"8384 Dempsey",
"Brooklyn",
"NY",
"01234");
Invoice ezInv(ezAddr, 10);
ezInv.add(Product("Power Cleaner", 49.95), 1);
ezInv.add(Product("PX Cleaner Fluid", 9.00), 8);
ezInv.add(Product("M803 Vac Bags", 2.08), 10);
cout << ezInv.format() << endl;
return 0;
}
The responsibilities for formatting and printing the invoice
are distributed over the classes as a result of the design
phase. No one class has to do everything and so each class can
be easier to understand and implement.
In general, this CRC technique can provide an effective way of
modularizing a program using object oriented
features. Classes are designed and Responsibilities are
assigned to the chosen class objects
with the goal of building a system according to specified
requirements.
This test program should produce the invoice:
Invoice
EZ Rental
8384 Dempsey
Brooklyn, NY 01234
Description Qty Price Total
------------------------------------------------------
Power Cleaner 1 $49.95 49.95
PX Cleaner Fluid 8 $ 9.00 72.00
M803 Vac Bags 10 $ 2.08 20.80
Amount Due: $142.75
How can you print the headings:
Description Qty Price Total
so that
- "Description" is left justified in a field of 25 character
positions
- "Qty", "Price" and "Total" are each one right
justifed in a field of 10 character positions.
- include <iomanip>
- Use cout << setw(25) to cause the next item
output be in a field of 25 character positions
- cout.setf(ios::left, ios::adjustfield) causes an
item that needs fewer character positions than the field to be
placed in the left most positions (and padded with the fill
character, i.e., blanks)
- cout.setf(ios::right, ios::adjustfield) causes an
item that needs fewer character positions than the field to be
placed in the right most positions (and padded with the fill
character, i.e., blanks)
cout.setf(ios::left, ios::adjustfield);
cout << setw(15) << "Description";
cout.setf(ios::right, ios::adjustfield);
cout << setw(10) << "Qty"
<< setw(10) << "Price"
<< setw(10) << "Total" << endl;
How can you create a format string instead of printing the
previous heading?
#include <sstream>
string format()
{
stringstream ss;
ss.setf(ios::left, ios::adjustfield);
ss << setw(15) << "Description";
ss.setf(ios::right, ios::adjustfield);
ss << setw(10) << "Qty"
<< setw(10) << "Price"
<< setw(10) << "Total" << endl;
return ss.str();
}
How can you print a line of 55 "-" without typing all 55 characters?
When an output value needs fewer character positions than the output
field, the value is padding with the 'fill' character either on
the left or on the right depending on the justification
desired.
The fill character, by default, is a blank.
But you can change the fill character. For example, you can
make the fill character be '-'.
Then to print 55 '-' characters:
- change the fill character to '-'
- print an empty string in a field of width 55
- change the fill character back to a blank
cout.fill('-');
cout << setw(55) << "" << endl;
cout.fill(' ');
How do you print floats and doubles in fixed decimal format
(not scientific notation) and with 2 decimal places?
- set the output default for floats and doubles to be
fixed
- set the output default precision to be 2 decimal places
cout.setf(ios::fixed);
cout.precision(2);
An object oriented program is to be designed that can print
bank statement for a checking account or a savings account. The
printed output of each kind of statement will contain the
customer's name and address and account number. The current
balance will be printed on a separate line. Then each detail line
of a statement will show the date, deposit or withdrawal (in
separate columns), the amount of the transaction, and the balance
after
the transaction is processed. For a savings account, the interest
earned depends on the interest rate which is the same for all
savings accounts. The earned interest is computed simply as the
monthly interest rate times the minimum balance in the account for
the month. For a checking account, there is no service charge for
the first 10 checks. After that there is a service charge of .05
per
check. The service charge is shown on a separate line on the
checking account statement.
Use the CRC (classes, responsibilities, collaborators)
technique to propose a list of classes that could be useful in
writing this program. For each of your classes, give:
- its responsibilities
- what other classes it will use (if any); i.e., the
collaborators
- For each collaborator of a class, indicate whether the class
will have a data member of the type of the collaborator
class
Two kinds of strings:
C strings are just ordinary arrays of char, with the
last char being the character with all bits 0. This can be
represented using single quotes as '\0', but not
'0'. The '0' is the character for the digit 0.
Here are the 8 bit patterns for each character:
character |
8 bit Representation |
decimal integer value |
'\0' |
0000 0000 |
0 |
'0' |
0011 0000 |
48 |
'1' |
0011 0001 |
49 |
'2' |
0011 0010 |
50 |
Since a C string is not really a separate type, but just a
array of chars (special because the last char should be '\0'),
declarations and operations are defined and implemented terms of
char arrays.
char s1[] = {'C', 'a', 't', '\0'};
char s2[] = "Cat";
char s3[4] = "Cat";
cout << s1 << endl;
cout << s2 << endl;
cout << s3 << endl;
All 3 print the same output:
Cat
- String Length
- Assignment/Copying
- Comparison
- Concatenation
- Searching
- Splitting
#include <cstring>
int strlen(const char *s);
Example:
int main()
{
char s1[4] = {'C', 'a', 't', '\0'};
int length;
length = strlen(s1);
cout << s1 << endl;
cout << "length = " << length << endl;
}
Output: 3 (not 4)
char * strcpy(char *dest, const char *source);
The 'const' means something can't be changed. What is that
something?
int main()
{
char s[] = "Hello, World!";
char m[50];
strcpy(m, s);
cout << m << endl;
}
Output: Hello, World!
int main()
{
char s[132];
cout << "Input a sentence on one line" << endl;
cin.getline(s,132);
char *m = new char[strlen(s) + 1];
strcpy(m, s);
cout << m << endl;
...
delete [] m;
}
Output: (the input sentence)
int strcmp(const char *s1, const char* s2);
Return value of strcmp(str1, str2) |
Meaning |
less than 0 |
str1 is less than str2 |
equals 0 |
str1 is equal to str2 |
greater than 0 |
str1 is greater than str2 |
There are functions to search for the first occurrence of a
given char in a string or to search for the first occurence of a
string as a substring in another string.
char * strchr(const char *str1, int ch);
char * strstr(const char *str1, const char *str2);
Both return NULL if the second parameter is not found
in str1.
A handy function for splitting a string into substrings is
char * strtok(char *str1, const char *delims);
The strtok function returns a pointer to the next .token. in
str1, where str2 contains the delimiters that determine the
token. strtok returns NULL if no token is found.
In order to convert a string to tokens, the first call to
strtok should have str1 point to the string to be
tokenized. All calls afterwards should have str1 be NULL.
...
#include <cstring>
int main()
{
string line;
cout << "\nEnter a line with comma separated values" << endl;
getline(cin, line);
const char *s = line.c_str();
char *p = new char[strlen(s) + 1];
strcpy(p, s);
char *q;
q = strtok(p, ";");
while( q != NULL ) {
cout << q << endl;
q = strtok(NULL, ";");
}
return 0;
}
Input Line: Jason R Bloch;5512 Garden Lakes Dr.;Flushing, NY 01234
Output:
Jason R Bloch
5512 Garden Lakes Dr.
Flushing, NY 01234
- change case (one letter at a time)
int toupper(int ch);
int tolower(int ch);
Example:
char s[] = "hello";
s[0] = toupper(s[0]);
cout << s << endl;
Output: Hello
-
setting all char array members to the same char
char s[100000];
memset(s, 'X', 100000);
This sets all elements to be 'X' and is much faster than
writing a loop (maybe 15 to 20 times as fast for arrays this
size.).
int main()
{
string line;
ifstream ifs;
string fname;
cout << "Address file name: ";
cin >> fname;
ifs.open(fname.c_str());
if (!ifs.is_open()) {
cout << "Unable to open input file '" << fname << "'" << endl;
exit(0);
}
// Now process the file
...
}
class Employee
{
char *name;
double salary;
public:
Employee();
Employee(char nm[], double sal);
Employee(const Employee& other);
const char * getName() const;
double getSalary() const;
void setSalary(double newSalary);
void operator=(const Employee& other);
~Employee();
};
Implementation of second constructor and the destructor:
Employee::Employee(char nm[], double sal)
{
name = new char[strlen(nm) + 1];
strcpy(name, nm);
salary = sal;
}
Employee::~Employee()
{
delete [] name;
}
C++ strings are a new type: string.
This type is defined by the string class.
There are many member functions and also many overloaded
non-member operators.
The string class has its own assignment operator, copy
constructor, and destructor. So in general, you don't have to
manage memory for C++ strings
- Assignment/Copying
string s1 = "Hello":
string s2;
s2 = s1; // s2 gets a copy of s1.
- Comparison
string s1 = "Hello";
string s2 = "World";
if ( s1 < s2 ) {
cout << s1 " comes before " << s2 << endl;
}
- Concatenation
string s1 = "Hello";
string s2 = "World!";
string s;
s = s1 + ", " + s2;
cout << s << endl;
Output: Hello, World!
- Searching