Answers
Day 1
Quiz
1. What is the difference between interpreters and
compilers?
Interpreters read through source code and translate a program, turning
the programmer's code, or program instructions, directly into actions.
Compilers translate source code into an executable program that can be run at a
later time.
2. How do you compile the source code with your
compiler?
Every
compiler is different. Be sure to check the documentation that came with your
compiler.
3. What does the linker do?
The linker's job is to tie together your compiled code with the
libraries supplied by your compiler vendor and other sources. The linker lets
you build your program in pieces and then link together the pieces into one big
program.
4. What are the steps in the development cycle?
Edit
source code, compile, link, test, repeat.
Exercises
Initializes two integer variables
and then prints out their sum and their product.
See your compiler manual.
You must put a # symbol before the word include on the
first line.
This program prints the words Hello
World to the screen, followed by a new line (carriage
return).
Day 2
1. What is the difference between the compiler and
the preprocessor?
Each time you run your compiler, the preprocessor runs first. It reads
through your source code and includes the files you've asked for, and performs
other housekeeping chores. The preprocessor is discussed in detail on Day 18,
"Object-Oriented Analysis and Design."
2. Why is the function main() special?
main() is called
automatically, each time your program is executed.
3. What are the two types of comments, and how do
they differ?
C++-style comments are two slashes (//), and
they comment out any text until the end of the line. C-style comments come in
pairs (/* */), and
everything between the matching pairs is commented out. You must be careful to
ensure you have matched pairs.
4. Can comments be nested?
Yes, C++-style comments can be nested within C-style comments. You can,
in fact, nest C-style comments within C++-style comments, as long as you
remember that the C++-style comments end at the end of the line.
5. Can comments be longer than one line?
C-style comments can. If you want to extend C++-style comments to a
second line, you must put another set of double slashes (//).
Exercises
Write a program that writes I love C++ to the
screen.
#include
<iostream.h>
2:
int
main()
{
cout
<< "I love C++\n";
return
0;
}
Write the smallest program that
can be compiled, linked, and run.
int main(){}
3. BUG BUSTERS: Enter this program and compile it.
Why does it fail? How can you fix it?
main()
{
cout
<< Is there a bug here?";
}
Line 4 is
missing an opening quote for the string.
Fix the bug in Exercise 3 and recompile, link, and
run it.
#include
<iostream.h>
main()
{
cout
<< "Is there a bug here?";
}
Day 3
Quiz
1. What is the difference between an integral
variable and a floating-point variable?
Integer variables are whole numbers; floating-point variables are
"reals" and have a "floating" decimal point. Floating-point
numbers can be represented using a mantissa and an exponent.
2. What are the differences between an unsigned short int and a long int?
The keyword unsigned means
that the integer will hold only positive numbers. On most computers, short
integers are 2 bytes and long integers are 4.
3. What are the advantages of using a symbolic
constant rather than a literal?
A symbolic constant explains itself; the name of the constant tells what
it is for. Also, symbolic constants can be redefined at one location in the
source code, rather than the programmer having to edit the code everywhere the
literal is used.
4. What are the advantages of using the const keyword rather than #define?
const
variables are "typed;" thus the compiler
can check for errors in how they are used. Also,
they survive the preprocessor; thus the name is available in the debugger.
5. What makes for a good or bad
variable name?
A good variable name tells you what the variable is for; a bad variable
name has no information. myAge and PeopleOnTheBus are good variable names, but xjk and prndl
are probably less useful.
enum COLOR { WHITE, BLACK = 100, RED, BLUE, GREEN = 300 }; BLUE
= 102
7. Which of the following variable names are good,
which are bad, and which are invalid?
Age
Good
!ex
Not legal
R79J
Legal,
but a bad choice
TotalIncome
Good
__Invalid
Legal,
but a bad choice
Exercises
1. What would be the correct
variable type in which to store the following information?
a. Your age.
Unsigned
short integer
b. The area of your backyard.
Unsigned long
integer or unsigned float
The number of stars in the galaxy.
Unsigned
double
The average rainfall for the
month of January.
Unsigned
short integer
Create good variable names for
this information.
a. myAge
b. backYardArea
c. StarsInGalaxy
d. averageRainFall
const
float PI = 3.14159;
4. Declare a float variable
and initialize it using your pi constant.
float
myPi = PI;
Day 4
Quiz
1. What is an expression?
Any
statement that returns a value.
2. Is x
= 5 + 7 an
expression? What is its value?
Yes. 12
3. What is the value of 201 / 4?
50
4. What is the value of 201 % 4?
1
5. If myAge, a, and b are all int variables, what are their values after:
myAge = 39; a = myAge++;
b = ++myAge;
myAge: 41, a: 39, b: 41
6. What is the value of 8+2*3?
14
7. What is the difference between if(x = 3) and if(x == 3)?
The first one assigns 3 to x and returns true. The second one tests whether x is equal to 3; it returns true if the value of
x is equal to 3 and false if it is
not.
0
FALSE
1
TRUE
-1
TRUE
x = 0
FALSE
x == 0 //
assume that x has the value of 0
TRUE
Exercises
1. Write a
single if statement that examines two integer variables and changes the larger to the smaller, using only one else clause.
if (x > y) x = y;
else //
y > x || y == x
y
= x;
2. Examine the following program. Imagine entering three numbers, and write
what output you expect.
#include
<iostream.h>
int
main()
{
int
a, b, c;
cout
<< "Please enter three numbers\n";
cout
<< "a: ";
cin
>> a;
cout
<< "\nb: ";
cin
>> b;
cout
<< "\nc: ";
cin
>> c;
12:
if
(c = (a-b))
14
|
{
|
15:
|
cout << "a: " << a << "
minus b: ";
|
16:
|
cout
<< b << " _equals c: " << c;
|
}
else
return
0;
}
Enter the program from Exercise 2; compile, link,
and run it. Enter the numbers 20, 10, and
Did you get the output you
expected? Why not?
Enter 20, 10, 50.
Get back a: 20 b: 30 c:
10.
Line 13
is assigning, not testing for equality.
Examine this program and anticipate the output:
#include
<iostream.h>
int
main()
{
4: int a = 2, b = 2, c; 5: if (c = (a-b))
6: cout
<< "The value of c is: " << c;
return
0;
}
Enter, compile, link, and run the program from
Exercise 4. What was the output? Why?
Because line 5 is assigning the value of a-b to c, the value of the assignment is a (1) minus b (1), or 0. Because 0 is evaluated as FALSE, the if fails and nothing is printed.
Day 5
Quiz
1. What are the differences
between the function prototype and the function defi-nition?
The function prototype declares the function; the definition defines it.
The prototype ends with a semicolon; the definition need not. The declaration
can include the keyword inline and
default values for the parameters; the definition cannot. The
declaration need not include names for the parameters; the definition must.
2. Do the names of parameters
have to agree in the prototype, definition, and call to the function?
No. All parameters are identified by position, not name.
Declare the function to return void.
4. If you don't declare a return value, what type of return value is
assumed?
Any function that does not
explicitly declare a return type returns int.
5. What is a local variable?
A local variable is a variable passed into or declared within a block,
typically a function. It is visible only within the block.
6. What is scope?
Scope refers to the visibility and lifetime of local and global
variables. Scope is usually established by a set of braces.
7. What is recursion?
Recursion generally refers to the
ability of a function to call itself.
8. When should you use global variables?
Global
variables are typically used when many functions need access to the same data.
Global variables are very rare in C++; once you know how to create static class
variables, you will almost never create global variables.
9. What is function overloading?
Function overloading is the ability to write more than one function with
the same name, distinguished by the number or type of the parameters.
10. What is polymorphism?
Polymorphism is the ability to treat many objects of differing but
related types without regard to their differences. In C++, polymorphism is
accomplished by using class derivation and virtual functions.
Exercises
Write the prototype for a
function named Perimeter, which
returns an unsigned long
int and which takes two parameters, both
unsigned short ints. unsigned long int Perimeter(unsigned short int, unsigned
short int);
Write the definition of the function
Perimeter as
described in Exercise 1. The two parameters represent the length and width of a
rectangle and have the function return the
unsigned
long int Perimeter(unsigned short int length, unsigned short int width)
{
return
2*length + 2*width;
}
3. BUG BUSTERS: What is wrong with
the function?
#include
<iostream.h>
void myFunc(unsigned short int x); int main()
{
unsigned short int x, y; y = myFunc(int);
cout << "x: " << x << "
y: " << y << "\n"; return 0;
}
void myFunc(unsigned
short int x)
{
return
(4*x);
}
The
function is declared to return void and it cannot return a value.
4. BUG BUSTERS: What is wrong with
the function?
#include
<iostream.h>
int myFunc(unsigned short int x); int main()
{
unsigned short int x, y; y = myFunc(int);
cout << "x: " << x << "
y: " << y << "\n"; return 0;
}
int myFunc(unsigned
short int x)
{
return
(4*x);
}
This function would be fine, but
there is a semicolon at the end of the function definition's
5. Write a function that takes two unsigned
short int arguments and returns the result of
dividing the first by the second. Do not do the division if the second number
is 0, but do return -1.
short
int Divider(unsigned
short int valOne, unsigned
short int valTwo)
{
if (valTwo == 0) return -1;
else
return
valOne / valTwo;
}
6. Write a program that asks the user for two numbers and calls the
function you wrote in Exercise 5.
Print the answer, or print an error message if you get -1.
#include
<iostream.h>
typedef unsigned short int USHORT; typedef unsigned long int
ULONG; short int Divider(
unsigned short int valone, unsigned short int valtwo); int
main()
{
USHORT one, two; short int answer;
cout << "Enter two numbers.\n Number one: "; cin
>> one;
cout << "Number two: "; cin >> two;
answer = Divider(one, two); if (answer > -1)
cout << "Answer: " << answer; else
cout << "Error, can't divide by zero!";
return 0;
}
7. Write a program that asks for a number and a power. Write a recursive
function that takes the number to
the power. Thus, if the number is 2 and the power is 4, the function will
return
16.
#include
<iostream.h>
typedef unsigned short
USHORT;
ULONG GetPower(USHORT n, USHORT power); int main()
{
USHORT
number, power;
ULONG
answer;
cout << "Enter a number: "; cin >> number;
cout << "To what power? "; cin >> power;
answer
= GetPower(number,power);
cout << number << " to the "
<< power << "th power is " << answer << endl;
return 0;
}
ULONG GetPower(USHORT
n, USHORT power)
{
if(power == 1) return n;
else
return
(n * GetPower(n,power-1));
}
Day 6
Quiz
1. What is the dot operator, and what is it used
for?
The dot
operator is the period (.). It is used to access the members of the class.
2. Which sets aside memory--declaration or
definition?
Definitions of variables set aside memory. Declarations of classes don't
set aside memory.
3. Is the declaration of a class
its interface or its implementation?
The declaration of a class is its interface; it tells clients of the
class how to interact with the class. The implementation of the class is the
set of member functions stored--usually in a related CPP file.
4. What is the difference between
public and private data members?
Public data members can be accessed by clients of the class. Private
data members can be accessed only by member functions of the class.
Yes. Both
member functions and member data can be private.
6. Can member data be public?
Although member data can be public, it is good programming practice to
make it private and to provide public accessor functions to the data.
7. If you declare two Cat objects, can they have different values in their itsAge member data?
Yes. Each
object of a class has its own data members.
8. Do class declarations end with a semicolon? Do
class method definitions?
Declarations
end with a semicolon after the closing brace; function definitions do not.
9. What would the header for a Cat function, Meow, that takes no parameters and
returns void look like?
The header for a Cat function, Meow(), that takes no parameters and returns void looks like this:
void Cat::Meow()
10. What function is called to initialize a class?
The
constructor is called to initialize a class.
Exercises
1. Write the code that declares a class called Employee with these data members: age, yearsOfService, and Salary.
class Employee
{
int
Age;
int YearsOfService; int Salary;
};
2. Rewrite the Employee class to make the data members private, and provide public accessor methods to get and set each
of the data members.
class Employee
{
int GetAge() const; void SetAge(int age);
int GetYearsOfService()const; void SetYearsOfService(int years);
int GetSalary()const;
void
SetSalary(int salary);
private: int Age;
int YearsOfService; int Salary;
};
3. Write a
program with the Employee class that makes two Employees; sets their age, YearsOfService, and Salary; and
prints their values.
main()
{
Employee
John;
Employee
Sally;
John.SetAge(30);
John.SetYearsOfService(5);
John.SetSalary(50000);
Sally.SetAge(32);
Sally.SetYearsOfService(8);
Sally.SetSalary(40000);
cout <<
|
"At
AcmeSexist company, John and Sally have the same
|
job.\n";
|
|
cout <<
|
"John
is " << John.GetAge() << " years old and he has
|
been with";
|
|
cout <<
|
"the
firm for " << John.GetYearsOfService << "
|
years.\n";
|
|
cout <<
|
"John
earns $" << John.GetSalary << " dollars per
|
year.\n\n";
|
|
cout <<
|
"Sally,
on the other hand is " << Sally.GetAge() << "
|
years old and
has";
|
|
cout <<
|
"been
with the company " << Sally.GetYearsOfService;
|
cout <<
|
" years. Yet Sally only makes $" <<
Sally.GetSalary();
|
cout <<
|
"
dollars per year! Something here is
unfair.";
|
4. Continuing from Exercise 3, provide a method of Employee that reports how many thousands of dollars the employee
earns, rounded to the nearest 1,000.
{
return
Salary / 1000;
}
5. Change the Employee class so that you can initialize age, YearsOfService, and Salary
when you create the employee.
class Employee
{
public:
Employee(int age, int yearsOfService, int salary); int
GetAge()const;
void
SetAge(int age);
int GetYearsOfService()const; void SetYearsOfService(int years);
int GetSalary()const;
void
SetSalary(int salary);
private: int Age;
int YearsOfService; int Salary;
};
6. BUG BUSTERS: What is wrong with
the following declaration?
class Square
{
public:
int
Side;
}
Class declarations must end with a semicolon.
7. BUG BUSTERS: Why isn't the following class declaration very useful?
class Cat
{
int GetAge()const; private:
int
itsAge;
};
The
accessor GetAge() is private. Remember: All class members are
private unless you say
8. BUG BUSTERS: What three bugs in
this code will the compiler find?
class TV
{
public:
void SetStation(int Station); int GetStation() const;
private:
int
itsStation;
};
main()
{
TV myTV; myTV.itsStation = 9;
TV.SetStation(10);
TV
myOtherTv(2);
}
You can't
access itsStation directly. It is private.
You can't call SetStation() on the
class. You can call SetStation() only on
objects. You can't initialize itsStation because
there is no matching constructor.
Day 7
Quiz
1. How do I initialize more than one variable in a for loop?
Separate
the initializations with commas, such as
for (x = 0, y = 10; x
< 100; x++, y++)
2. Why is goto avoided?
goto
jumps in any direction to any arbitrary line of
code. This makes for source code that is difficult
to understand and therefore difficult to maintain.
3. Is it possible to write a for loop
with a body that is never executed?
Yes, if the condition is FALSE after
the initialization, the body of the for loop
will never execute. Here's an example:
for (int x = 100; x
< 100; x++)
Yes. Any
loop can be nested within any other loop.
5. Is it possible to create a loop that never ends?
Give an example.
Yes.
Following are examples for both a for loop and
a while loop:
for(;;)
{
//
This for loop never ends!
}
while(1)
{
//
This while loop never ends!
}
6. What happens if you create a loop that never
ends?
Your
program hangs, and you usually must reboot the computer.
Exercises
1. What is the value of x when the for loop completes?
for (int x = 0; x <
100; x++)
100
2. Write a nested for loop that prints a 10x10 pattern of 0s.
for (int i = 0; i<
10; i++)
{
for ( int j = 0; j< 10; j++) cout <<
"0";
cout
<< "\n";
}
3. Write a for statement
to count from 100 to 200 by 2s.
for (int x = 100;
x<=200; x+=2)
4. Write a while loop to
count from 100 to 200 by 2s.
x+=
2;
5. Write a do...while loop to
count from 100 to 200 by 2s.
int x = 100; do
{
x+=2;
}
while (x <= 200);
BUG BUSTERS: What is wrong with this code?
int counter = 0 while (counter < 10)
{
cout << "counter: " << counter; counter++;
}
counter is never
incremented and the while loop will never terminate.
7. BUG BUSTERS: What is wrong with
this code?
for (int counter = 0; counter < 10; counter++); cout
<< counter << "\n";
There is a semicolon after the loop, and the loop does nothing. The
programmer may have intended this, but if counter was supposed to print each value, it won't.
8. BUG BUSTERS: What is wrong with
this code?
int counter = 100; while (counter < 10)
{
cout << "counter now: " << counter;
counter--;
}
counter
is initialized to 100, but the test condition is that if it is less than 10, the test will
fail and the body will never be executed. If line 1
were changed to int counter = 5;, the
loop would not terminate until it had counted down past the smallest
possible int. Because int
is signed by
default, this would not be what was intended.
cout <<
|
"Enter a number
|
between 0 and 5: ";
|
cin >>
theNumber;
|
||
switch (theNumber)
|
||
{
|
||
case
0:
|
||
doZero();
|
||
case
1:
|
//
fall through
|
|
case
2:
|
//
fall through
|
|
case
3:
|
//
fall through
|
|
case
4:
|
//
fall through
|
|
case
5:
|
||
doOneToFive();
|
break;
default:
doDefault();
break;
}
Case
0 probably needs a break statement.
If it does not, it should be documented with a comment.
Day 8
Quiz
1. What operator is used to determine the address
of a variable?
The
address of operator (&) is used to determine the
address of any variable.
2. What operator is used to find the value stored
at an address held in a pointer?
The
dereference operator (*) is used to access the value at an address in a
pointer.
3. What is a pointer?
A pointer is a variable that holds the address of another variable.
4. What is the difference between
the address stored in a pointer and the value at that
address?
The address stored in the pointer is the address of another variable.
The value stored at that address is any value stored in any variable. The
indirection operator (*) returns the value stored at the
address, which itself is stored in the pointer.
The indirection operator returns the value at the address stored in a
pointer. The address of operator (&) returns the memory address of the variable.
6. What is the difference between
const int *
ptrOne and int * const ptrTwo?
The const int * ptrOne declares
that
ptrOne is a pointer to a constant integer. The
integer itself cannot be changed using this pointer.
The int * const ptrTwo declares
that ptrTwo is a constant pointer to an
integer. Once it is initialized, this pointer cannot be reassigned.
Exercises
1. What do these declarations do?
a. int
* pOne; b. int
vTwo;
c. int * pThree = &vTwo;
int * pOne; declares a pointer to an integer.
int vTwo; declares
an integer variable.
int * pThree = &vTwo; declares
a pointer to an integer and initializes it with
the address of another variable.
2. If you have an unsigned
short variable named yourAge, how would you declare a pointer
to manipulate yourAge?
unsigned short *pAge =
&yourAge;
3. Assign the value 50 to the variable yourAge by using the pointer that you declared in Exercise 2.
*pAge = 50;
4. Write a small program that declares an integer and a pointer to integer.
Assign the address of the integer to
the pointer. Use the pointer to set a value in the integer variable.
int theInteger;
int *pInteger = &theInteger; *pInteger = 5;
5. BUG BUSTERS: What is wrong with this code?
#include
<iostream.h>
{
int *pInt; *pInt = 9;
cout << "The value at pInt: " <<
*pInt; return 0;
}
pInt
should have been initialized. More importantly,
because it was not initialized and was not
assigned the address of any memory, it points to a random place in memory.
Assigning 9 to that random place is a
dangerous bug.
6. BUG BUSTERS: What is wrong with
this code?
int main()
{
int
SomeVariable = 5;
cout << "SomeVariable: " << SomeVariable
<< "\n"; int *pVar = & SomeVariable;
pVar
= 9;
cout << "SomeVariable: " << *pVar
<< "\n"; return 0;
}
Presumably, the programmer meant to assign 9 to the value at pVar.
Unfortunately, 9 was assigned to be the value of pVar because the indirection operator (*) was
left off. This will lead to disaster if pVar is used
to assign a value.
Day 9
Quiz
1. What is the difference between a reference and a
pointer?
A reference is an alias, and a pointer is a variable that holds an
address. References cannot be null and cannot be assigned to.
2. When must you use a pointer
rather than a reference?
When you may need to reassign what is pointed to, or when the pointer
may be null.
3. What does new return if there is insufficient memory to make
your new object?
A null
pointer (0).
4. What is a constant reference?
5. What is the difference between passing by
reference and passing a reference?
Passing by reference means not making a local copy. It can be accomplished
by passing a reference or by passing a pointer.
Exercises
1. Write a
program that declares an int, a reference to an int, and a pointer to an int. Use the pointer and the
reference to manipulate the value in the int.
int main()
{
int varOne;
int& rVar = varOne; int* pVar = &varOne; rVar = 5;
*pVar = 7; return 0;
}
2. Write a program that declares a constant pointer to a constant integer.
Initialize the pointer to an integer
variable, varOne. Assign 6 to varOne. Use the
pointer to assign 7 to varOne.
Create a
second integer variable, varTwo. Reassign the pointer to varTwo.
int main()
{
int
varOne;
const
int * const pVar = &varOne;
*pVar = 7; int varTwo; pVar = &varTwo;
return 0;
}
Compile the program in Exercise
2. What produces errors? What produces warnings? You can't assign a value to a
constant object, and you can't reassign a constant pointer.
Write a program that produces a
stray pointer.
int main()
{
int * pVar; *pVar = 9;
}
5. Fix the program from Exercise 4.
int main()
{
int VarOne;
int * pVar = &varOne; *pVar = 9;
return 0;
}
6. Write a program that produces a
memory leak.
int FuncOne(); int main()
{
int
localVar = FunOne();
cout << "the value of localVar is: " <<
localVar; return 0;
}
int FuncOne()
{
int * pVar = new int (5); return *pVar;
}
7. Fix the program from Exercise 6.
void FuncOne(); int main()
{
FuncOne(); return 0;
}
void FuncOne()
{
int
* pVar = new int (5);
cout
<< "the value of *pVar is: " << *pVar ;
}
8. BUG BUSTERS: What is wrong with
this program?
class
CAT
{
public:
6:
|
CAT(int
age) { itsAge = age; }
|
7:
|
~CAT(){}
|
8:
|
int GetAge() const { return itsAge;}
|
private:
10:
|
int itsAge;
|
11:
|
};
|
12:
|
CAT
& MakeCat(int age);
int
main()
{
int
age = 7;
CAT
Boots = MakeCat(age);
cout
<< "Boots is " << Boots.GetAge() << " years
old\n";
return
0;
}
21:
CAT
& MakeCat(int age)
{
CAT
* pCat = new CAT(age);
return
*pCat;
}
MakeCat
returns a reference to the
CAT created on the free store. There is no way to free
that memory, and this produces a
memory leak.
Fix the program from Exercise 8.
#include
<iostream.h>
class
CAT
{
public:
6:
|
CAT(int
age) { itsAge = age; }
|
7:
|
~CAT(){}
|
8:
|
int GetAge() const { return itsAge;}
|
private:
10:
|
int itsAge;
|
11:
|
};
|
12:
|
CAT
* MakeCat(int age);
int
main()
int
age = 7;
CAT
* Boots = MakeCat(age);
cout
<< "Boots is " << Boots->GetAge() << "
years old\n";
delete
Boots;
return
0;
}
22:
CAT
* MakeCat(int age)
{
return
new CAT(age);
}
Day 10
Quiz
1. When you overload member
functions, in what ways must they differ?
Overloaded member functions are functions in a class that share a name
but differ in the number or type of their parameters.
2. What is the difference between a declaration and
a definition?
A definition sets aside memory, but a declaration does not. Almost all
declarations are definitions; the major exceptions are class declarations,
function prototypes, and typedef
statements.
3. When is the copy constructor called?
Whenever a temporary copy of an object is created. This happens every
time an object is passed by value.
4. When is the destructor called?
The destructor is called each time an object is destroyed, either
because it goes out of scope or because you call delete on a pointer pointing to it.
5. How does the copy constructor differ from the
assignment operator (=)?
The assignment operator acts on an existing object; the copy constructor
creates a new one.
6. What is the this pointer?
The this pointer
is a hidden parameter in every member function that points to the object
itself.
7. How do you differentiate between overloading the
prefix and postfix increments?
The prefix operator takes no parameters. The postfix operator takes a
single int parameter, which is used as a
signal to the compiler that this is the postfix variant.
8. Can you overload the operator+ for short integers?
No, you
cannot overload any operator for built-in types.
9. Is it legal in C++ to overload operator++ so that it decrements a value in your class?
It is legal, but it is a bad idea. Operators should be overloaded in a
way that is likely to be readily understood by anyone reading your code.
10. What return value must conversion operators
have in their declaration?
None.
Like constructors and destructors, they have no return values.
Exercises
1. Write a SimpleCircle class declaration (only) with one member variable: itsRadius. Include a default constructor, a
destructor, and accessor methods for itsRadius.
class SimpleCircle
{
public:
SimpleCircle();
~SimpleCircle(); void SetRadius(int); int GetRadius();
private:
int
itsRadius;
};
2. Using the class you created in Exercise 1, write the implementation of
the default constructor,
initializing itsRadius with the
value 5.
SimpleCircle::SimpleCircle():
itsRadius(5)
{}
3. Using the same class, add a second constructor that takes a value as its
parameter and assigns that value to itsRadius.
SimpleCircle::SimpleCircle(int radius): itsRadius(radius)
{}
4. Create a prefix and postfix increment operator for your SimpleCircle class that increments itsRadius.
const SimpleCircle&
SimpleCircle::operator++()
{
++(itsRadius); return *this;
}
Operator
++(int) postfix.
Fetch
then increment
const SimpleCircle SimpleCircle::operator++
(int)
{
// declare local SimpleCircle and initialize to value of
*this SimpleCircle temp(*this);
++(itsRadius); return temp;
}
5. Change SimpleCircle to store itsRadius on the free store, and fix the existing methods.
class SimpleCircle
{
public:
SimpleCircle();
SimpleCircle(int);
~SimpleCircle(); void SetRadius(int); int GetRadius();
const SimpleCircle& operator++(); const SimpleCircle
operator++(int);
private:
int
*itsRadius;
};
SimpleCircle::SimpleCircle()
{itsRadius = new
int(5);}
SimpleCircle::SimpleCircle(int
radius)
{itsRadius = new
int(radius);}
const SimpleCircle&
SimpleCircle::operator++()
{
++(itsRadius);
}
Operator
++(int) postfix.
Fetch
then increment
const SimpleCircle
SimpleCircle::operator++ (int)
{
// declare local SimpleCircle and initialize to value of
*this SimpleCircle temp(*this);
++(itsRadius); return temp;
}
6. Provide a copy constructor for SimpleCircle.
SimpleCircle::SimpleCircle(const
SimpleCircle & rhs)
{
int val = rhs.GetRadius(); itsRadius = new int(val);
}
7. Provide an operator= for SimpleCircle.
SimpleCircle&
SimpleCircle::operator=(const SimpleCircle & rhs)
{
if (this == &rhs) return *this;
delete itsRadius;
itsRadius
= new int;
*itsRadius = rhs.GetRadius(); return *this;
}
8. Write a program that creates two SimpleCircle objects. Use the default constructor on one and instantiate the other with the value 9. Call increment on each
and then print their
values. Finally, assign the second to the first and print its values.
#include
<iostream.h>
class SimpleCircle
{
public:
//
constructors
SimpleCircle();
SimpleCircle(int);
SimpleCircle(const
SimpleCircle &);
accessor functions void
SetRadius(int); int GetRadius()const;
operators
const SimpleCircle& operator++(); const SimpleCircle
operator++(int);
SimpleCircle&
operator=(const SimpleCircle &);
private:
int
*itsRadius;
};
SimpleCircle::SimpleCircle()
{itsRadius = new
int(5);}
SimpleCircle::SimpleCircle(int
radius)
{itsRadius = new
int(radius);}
SimpleCircle::SimpleCircle(const
SimpleCircle & rhs)
{
int val = rhs.GetRadius(); itsRadius = new int(val);
}
SimpleCircle&
SimpleCircle::operator=(const SimpleCircle & rhs)
{
if (this == &rhs) return *this;
*itsRadius = rhs.GetRadius(); return *this;
}
const SimpleCircle&
SimpleCircle::operator++()
{
++(itsRadius); return *this;
}
Operator
++(int) postfix.
Fetch
then increment
const SimpleCircle
SimpleCircle::operator++ (int)
{
// declare local SimpleCircle and initialize to value of *this
SimpleCircle temp(*this);
++(itsRadius);
}
int
SimpleCircle::GetRadius() const
{
return
*itsRadius;
}
int main()
{
SimpleCircle
CircleOne, CircleTwo(9);
CircleOne++;
++CircleTwo;
cout << "CircleOne: " <<
CircleOne.GetRadius() << endl; cout << "CircleTwo: "
<< CircleTwo.GetRadius() << endl;
CircleOne
= CircleTwo;
cout << "CircleOne: " <<
CircleOne.GetRadius() << endl; cout << "CircleTwo: "
<< CircleTwo.GetRadius() << endl;
return 0;
}
9. BUG BUSTERS: What is wrong with
this implementation of the assignment operator?
SQUARE SQUARE
::operator=(const SQUARE & rhs)
{
itsSide = new int; *itsSide = rhs.GetSide(); return *this;
}
You must check to see whether rhs equals this, or the call to a = a will
crash your program.
10. BUG BUSTERS: What is wrong with
this implementation of operator+?
VeryShort VeryShort::operator+
(const VeryShort& rhs)
{
itsVal += rhs.GetItsVal(); return *this;
}
This operator+ is
changing the value in one of the operands, rather than creating a new VeryShort
object with the sum. The right way to do this is as
follows:
VeryShort VeryShort::operator+
(const VeryShort& rhs)
{
return
VeryShort(itsVal + rhs.GetItsVal());
Day 11
Quiz
1. What are the first and last elements in SomeArray[25]?
SomeArray[0], SomeArray[24]
2. How do you declare a multidimensional array?
Write a set of subscripts for each dimension. For example, SomeArray[2][3][2] is a three-dimensional array. The first dimension has two elements, the
second has three, and the third has two.
3. Initialize the members of the array in Question
2.
SomeArray[2][3][2] = { { {1,2},{3,4},{5,6} } , {
{7,8},{9,10},{11,12} } };
4. How many elements are in the array SomeArray[10][5][20]?
10x5x20=1,000
5. What is the maximum number of elements that you
can add to a linked list?
There is
no fixed maximum. It depends on how much memory you have available.
6. Can you use subscript notation on a linked list?
You can use subscript notation on a linked list only by writing your own
class to contain the linked list and overloading the subscript operator.
7. What is the last character in
the string "Brad is a nice guy"?
The null character.
Exercises
1. Declare a two-dimensional array that represents a tic-tac-toe game
board.
int GameBoard[3][3];
2. Write the code that initializes all the elements in the array you
created in Exercise 1 to the value 0.
3. Write the declaration for a Node class that holds unsigned short integers.
class
Node
{
public:
Node
();
Node (int); ~Node();
void SetNext(Node * node) { itsNext = node; } Node * GetNext()
const { return itsNext; } int GetVal() const { return itsVal; }
void Insert(Node *); void Display();
private:
int itsVal; Node * itsNext;
};
4. BUG BUSTERS: What is wrong with
this code fragment?
unsigned short SomeArray[5][4]; for (int i = 0; i<4; i++)
for
(int j = 0; j<5; j++)
SomeArray[i][j]
= i+j;
The array
is 5 elements by 4 elements, but the code initializes 4x5.
5. BUG BUSTERS: What is wrong with
this code fragment?
unsigned short SomeArray[5][4]; for (int i = 0; i<=5; i++)
for
(int j = 0; j<=4; j++)
SomeArray[i][j]
= 0;
You wanted to write i<5, but you
wrote i<=5 instead.
The code will run when i == 5 and j
== 4, but there is no such element as
SomeArray[5][4].
Day 12
Quiz
1. What is a v-table?
A v-table, or virtual function
table, is a common way for compilers to manage virtual functions in C++. The
table keeps a list of the addresses of all the virtual functions and, depending
on the runtime type of the object pointed to, invokes the right function.
2. What is a virtual destructor?
A destructor of any class can be declared to be virtual. When the
pointer is deleted, the runtime type of the object will be assessed and the
correct derived destructor invoked.
3. How do you show the declaration of a virtual
constructor?
There are
no virtual constructors.
4. How can you create a virtual copy constructor?
By
creating a virtual method in your class, which itself calls the copy
constructor.
5. How do you invoke a base
member function from a derived class in which you've overridden that function?
Base::FunctionName();
6. How do you invoke a base
member function from a derived class in which you have not overridden that
function?
FunctionName();
7. If a base class declares a
function to be virtual, and a derived class does not use the term virtual when overriding that class, is it still virtual
when inherited by a third-
generation class?
Yes, the
virtuality is inherited and cannot be turned off.
8. What is the protected keyword used for?
protected members
are accessible to the member functions of derived objects.
Exercises
1. Show the declaration of a virtual
function taking an integer parameter and returning void.
virtual void
SomeFunction(int);
2. Show the declaration of a class Square, which derives from Rectangle, which in turn derives from Shape.
{};
3. If, in Exercise 2, Shape takes no parameters, Rectangle takes two (length and width), and
Square takes only one (length), show the constructor initialization for
Square.
Square::Square(int
length):
Rectangle(length,
length){}
4. Write a virtual copy constructor
for the class Square (from the preceding question).
class Square
{
public: // ...
virtual
Square * clone() const { return new Square(*this);
}
//
...
};
5. BUG BUSTERS: What is wrong with
this code snippet?
void SomeFunction
(Shape);
Shape * pRect = new
Rectangle;
SomeFunction(*pRect);
Perhaps nothing. SomeFunction expects
a Shape object. You've passed it a Rectangle "sliced" down to a Shape. As long
as you don't need any of the Rectangle parts,
this will be fine. If you do need the Rectangle parts, you'll need to change SomeFunction to take a pointer or a reference to a Shape.
6. BUG BUSTERS: What is wrong with this code snippet?
class Shape()
{
public:
Shape();
virtual
~Shape();
virtual
Shape(const Shape&);
};
You can't declare a copy constructor to be virtual.
Day 13
1. What is a down cast?
A down cast (also called "casting down") is a declaration that
a pointer to a base class is to be treated as a pointer to a derived class.
2. What is the v-ptr?
The v-ptr, or virtual-function pointer, is an implementation detail of
virtual functions. Each object in a class with virtual functions has a v-ptr,
which points to the virtual function table for that class.
3. If a
round rectangle has straight edges and rounded corners, your RoundRect class inherits both from Rectangle and from Circle, and they in turn both inherit from Shape, how many Shapes are created when you create a RoundRect?
If neither class inherits using the keyword virtual, two Shapes are
created: one for Rectangle and one
for Shape. If the
keyword virtual is used
for both classes, only one
shared Shape is
created.
4. If Horse and Bird inherit virtual
public from Animal, do their constructors initialize the Animal constructor? If Pegasus inherits from both Horse and Bird, how does it initialize Animal's constructor?
Both Horse and Bird initialize their base class, Animal, in
their constructors. Pegasus does as
well, and when a Pegasus is
created, the Horse and Bird initializations of Animal are
ignored.
5. Declare a class Vehicle and make it an abstract data type.
class Vehicle
{
virtual
void Move() = 0;
}
6. If a base class is an ADT, and
it has three pure virtual functions, how many of these functions must be
overridden in its derived classes?
None must be overridden unless you want to make the class non-abstract,
in which case all three must be overridden.
Exercises
1. Show the declaration for a class JetPlane, which
inherits from Rocket and Airplane.
2. Show the declaration for 747, which inherits from the JetPlane class described in Exercise
1.
class 747 : public
JetPlane
3. Show the declarations for the classes Car and Bus, which each derive from the
class Vehicle. Make Vehicle an ADT
with two pure virtual functions. Make Car and Bus not
be ADTs.
class Vehicle
{
virtual void Move() = 0; virtual void Haul() = 0;
};
class Car : public
Vehicle
{
virtual void Move(); virtual void Haul();
};
class Bus : public
Vehicle
{
virtual void Move(); virtual void Haul();
};
4. Modify the program in Exercise 1 so that Car is an ADT, and derive SportsCar and Coupe from
Car. In the Car class,
provide an implementation for one of the pure virtual
functions in Vehicle and make
it non-pure.
class Vehicle
{
virtual void Move() = 0; virtual void Haul() = 0;
};
class Car : public
Vehicle
{
virtual
void Move();
};
class Bus : public
Vehicle
{
};
class SportsCar :
public Car
{
virtual
void Haul();
};
class Coupe : public
Car
{
virtual
void Haul();
};
Day 14
Quiz
1. Can static member variables be private?
Yes. They are member variables, and their access can be controlled like
any other. If they are private, they can be accessed only by using member
functions or, more commonly, static member functions.
2. Show the declaration for a static member
variable.
static int itsStatic;
3. Show the declaration for a static function
pointer.
static int
SomeFunction();
4. Show the declaration for a
pointer to function returning long and taking an integer parameter.
long (* function)(int);
5. Modify the pointer in Exercise 4 to be a pointer
to member function of class Car
long (
Car::*function)(int);
6. Show the declaration for an
array of 10 pointers as defined in Exercise 5.
(long (
Car::*function)(int) theArray [10];
1. Write a short program declaring a class with one member variable and one
static member variable. Have the
constructor initialize the member variable and increment the static member
variable. Have the destructor decrement the member variable.
class
myClass
{
public:
myClass();
~myClass();
private:
int
itsMember;
static
int itsStatic;
};
10:
myClass::myClass():
itsMember(1)
{
itsStatic++;
}
16:
myClass::~myClass()
{
itsStatic--;
}
21:
22: int
myClass::itsStatic = 0;
23:
int
main()
{}
Using the program from Exercise
1, write a short driver program that makes three objects and then displays
their member variables and the static member variable. Then destroy each object
and show the effect on the static member variable.
1: #include
<iostream.h>
2:
class
myClass
{
public:
myClass();
~myClass();
void
ShowMember();
void
ShowStatic();
private:
static
int itsStatic;
};
14:
myClass::myClass():
itsMember(1)
{
itsStatic++;
}
20:
myClass::~myClass()
{
itsStatic--;
cout
<< "In destructor. ItsStatic: " << itsStatic <<
endl;
}
26:
void
myClass::ShowMember()
{
cout
<< "itsMember: " << itsMember << endl;
}
31:
void
myClass::ShowStatic()
{
cout
<< "itsStatic: " << itsStatic << endl;
}
int
myClass::itsStatic = 0;
37:
int
main()
{
myClass
obj1;
obj1.ShowMember();
obj1.ShowStatic();
myClass
obj2;
obj2.ShowMember();
obj2.ShowStatic();
myClass
obj3;
obj3.ShowMember();
obj3.ShowStatic();
return
0;
}
Modify the program from Exercise
2 to use a static member function to access the static member variable. Make
the static member variable private.
class
myClass
{
public:
myClass();
~myClass();
void
ShowMember();
static
int GetStatic();
private:
int
itsMember;
static
int itsStatic;
};
14:
myClass::myClass():
itsMember(1)
{
itsStatic++;
}
20:
myClass::~myClass()
{
itsStatic--;
cout
<< "In destructor. ItsStatic: " << itsStatic <<
endl;
}
26:
void
myClass::ShowMember()
{
cout
<< "itsMember: " << itsMember << endl;
}
31:
32: int
myClass::itsStatic = 0;
33:
void
myClass::GetStatic()
{
return
itsStatic;
}
38:
int
main()
{
myClass
obj1;
obj1.ShowMember();
cout
<< "Static: " << myClass::GetStatic() << endl;
obj2.ShowMember();
cout
<< "Static: " << myClass::GetStatic() << endl;
myClass
obj3;
obj3.ShowMember();
cout
<< "Static: " << myClass::GetStatic() << endl;
return
0;
}
Write a pointer to a member
function to access the non-static member data in the program in Exercise 3, and
use that pointer to print the value of that data.
1: #include <iostream.h> 2:
class
myClass
{
public:
myClass();
~myClass();
void
ShowMember();
static
int GetStatic();
private:
int
itsMember;
static
int itsStatic;
};
14:
myClass::myClass():
itsMember(1)
{
itsStatic++;
}
20:
myClass::~myClass()
{
itsStatic--;
cout
<< "In destructor. ItsStatic: " << itsStatic <<
endl;
}
26:
void
myClass::ShowMember()
{
cout
<< "itsMember: " << itsMember << endl;
}
31:
32: int
myClass::itsStatic = 0;
int
myClass::GetStatic()
{
return
itsStatic;
}
38:
int
main()
{
void
(myClass::*PMF) ();
43: PMF=myClass::ShowMember;
44:
myClass
obj1;
(obj1.*PMF)();
cout
<< "Static: " << myClass::GetStatic() << endl;
myClass
obj2;
(obj2.*PMF)();
cout
<< "Static: " << myClass::GetStatic() << endl;
myClass
obj3;
(obj3.*PMF)();
cout
<< "Static: " << myClass::GetStatic() << endl;
return
0;
}
Add two more member variables to
the class from the previous questions. Add accessor functions that get the
value of this data and give all the member functions the same return values and
signatures. Use the pointer to the member function to access these functions.
1: #include <iostream.h> 2:
class
myClass
{
public:
myClass();
~myClass();
void
ShowMember();
void
ShowSecond();
void
ShowThird();
static
int GetStatic();
private:
int
itsMember;
int
itsSecond;
int
itsThird;
static
int itsStatic;
18:
myClass::myClass():
itsMember(1),
itsSecond(2),
itsThird(3)
{
itsStatic++;
}
26:
myClass::~myClass()
{
itsStatic--;
cout
<< "In destructor. ItsStatic: " << itsStatic <<
endl;
}
32:
void
myClass::ShowMember()
{
cout
<< "itsMember: " << itsMember << endl;
}
37:
void
myClass::ShowSecond()
{
cout
<< "itsSecond: " << itsSecond << endl;
}
42:
void
myClass::ShowThird()
{
cout
<< "itsThird: " << itsThird << endl;
}
int
myClass::itsStatic = 0;
48:
int
myClass::GetStatic()
{
return
itsStatic;
}
53:
int
main()
{
void
(myClass::*PMF) ();
myClass
obj1;
PMF=myClass::ShowMember;
(obj1.*PMF)();
PMF=myClass::ShowSecond;
PMF=myClass::ShowThird;
(obj1.*PMF)();
cout
<< "Static: " << myClass::GetStatic() << endl;
myClass
obj2;
PMF=myClass::ShowMember;
(obj2.*PMF)();
PMF=myClass::ShowSecond;
(obj2.*PMF)();
PMF=myClass::ShowThird;
(obj2.*PMF)();
cout
<< "Static: " << myClass::GetStatic() << endl;
myClass
obj3;
PMF=myClass::ShowMember;
(obj3.*PMF)();
PMF=myClass::ShowSecond;
(obj3.*PMF)();
PMF=myClass::ShowThird;
(obj3.*PMF)();
cout
<< "Static: " << myClass::GetStatic() << endl;
return
0;
}
0 comments:
Post a Comment