Tải bản đầy đủ (.pdf) (20 trang)

C++ Primer Plus (P74) ppt

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (43.19 KB, 20 trang )

talents = 0;
}
ostream & operator<<(ostream & os, const nifty & n)
{
os << n.personality << '\n';
os << n.talent << '\n';
return os;
}
.5:Consider the following class declaration:
class Golfer
{
private:
char * fullname; // points to string containing golfer's name
int games; // holds number of golf games played
int * scores; // points to first element of array of golf scores
public:
Golfer();
Golfer(const char * name, int g= 0);
// creates empty dynamic array of g elements if g > 0
Golfer(const Golfer & g);
~Golfer();
} ;
What class methods would be invoked by each of the following statements?
Golfer nancy; // #1
Golfer lulu("Little Lulu"); // #2
Golfer roy("Roy Hobbs", 12); // #3
Golfer * par = new Golfer; // #4
Golfer next = lulu; // #5
Golfer hazzard = "Weed Thwacker"; // #6
*par = nancy; // #7
nancy = "Nancy Putter"; // #8


a.
This document was created by an unregistered ChmMagic, please go to to register it. Thanks.
Clearly, the class requires several more methods to make it useful, but what
additional method does it require to protect against data corruption?
b.
A:

Golfer nancy; // default constructor
Golfer lulu("Little Lulu"); // Golfer(const char * name, int g)
Golfer roy("Roy Hobbs", 12); // Golfer(const char * name, int g)
Golfer * par = new Golfer; // default constructor
Golfer next = lulu; // Golfer(const Golfer &g)
Golfer hazard = "Weed Thwacker"; // Golfer(const char * name, int g)
*par = nancy; // default assignment operator
nancy = "Nancy Putter";// Golfer(const char * name, int g), then
// the default assignment operator
Note
Some compilers will additionally call the
default assignment operator for statements #5
and #6.
a.
The class should define an assignment operator that copies data rather than
addresses.
b.
Chapter 13
.1:What does a derived class inherit from a base class?
A:The public members of the base class become public members of the derived
class. The protected members of the base class become protected members
of the derived class. The private members of the base class are inherited, but
cannot be accessed directly. The answer to review question 2 provides the

This document was created by an unregistered ChmMagic, please go to to register it. Thanks.
exceptions to these general rules.
.2:What doesn't a derived class inherit from a base class?
A:The constructor methods are not inherited, the destructor is not inherited, the
assignment operator is not inherited, and friends are not inherited.
.3:Suppose the return type for the baseDMA::operator=() function were
defined as void instead of baseDMA &. What effect, if any, would that have?
What if the return type were baseDMA instead of baseDMA &?
A:If the return type were void, you would still be able to use single assignment
but not chain assignment:
baseDMA magazine("Pandering to Glitz", 1);
baseDMA gift1, gift2, gift3;
gift1 = magazine; // ok
gift 2 = gift3 = gift1; // no longer valid
If the method returned an object instead of a reference, the method execution
would be slowed a bit because the return statement would involve copying the
object.
.4:In what order are class constructors and class destructors called when a
derived class object is created and deleted?
A:Constructors are called in the order of derivation, with the most ancestral
constructor called first. Destructors are called in the opposite order.
.5:If a derived class doesn't add any data members to the base class, does the
derived class require constructors?
A:Yes, every class requires its own constructors. If the derived class adds no
new members, the constructor can have an empty body, but it must exist.
.6:Suppose a base class and a derived class both define a method of the same
name and a derived class object invokes the method. What method is called?
This document was created by an unregistered ChmMagic, please go to to register it. Thanks.
A:Only the derived class method is called. It supersedes the base class
definition. A base class method is called only if the derived class does not

redefine the method or if you use the scope resolution operator. However, you
really should declare as virtual any functions that will be redefined.
.7:When should a derived class define an assignment operator?
A:The derived class should define an assignment operator if the derived class
constructors use the new or new [] operator to initialize pointers that are
members of that class. More generally, the derived class should define an
assignment operator if the default assignment is incorrect for derived class
members.
.8:Can you assign the address of an object of a derived class to a pointer to the
base class? Can you assign the address of an object of a base class to a
pointer to the derived class?
A:Yes, you can assign the address of an object of a derived class to a pointer to
the base class. You can assign the address of a base object to a pointer to a
derived class (downcasting) only by making an explicit type cast, and it is not
necessarily safe to use such a pointer.
.9:Can you assign an object of a derived class to an object of the base class?
Can you assign an object of a base class to an object of the derived class?
A:Yes, you can assign an object of a derived class to an object of the base
class. Any data members new to the derived type are not passed to the base
type, however. The program will use the base class assignment operator.
Assignment in the opposite direction (base to derived) is possible only if the
derived class defines a conversion operator, which is a constructor having a
reference to the base type as its sole argument, or else defines an assignment
operator with a base-class parameter.
.10:Suppose you define a function that takes a reference to a base class object as
an argument. Why can this function also use a derived class object as an
argument?
A:It can do so because C++ allows a reference to a base type to refer to any
This document was created by an unregistered ChmMagic, please go to to register it. Thanks.
type derived from that base.

.11:Suppose you define a function that takes a base class object as an argument
(that is, the function passes a base class object by value). Why can this
function also use a derived class object as an argument?
A:Passing an object by value invokes the copy constructor. Since the formal
argument is a base class object, the base class copy constructor is invoked.
The copy constructor has as its argument a reference to the base class, and
this reference can refer to the derived object passed as an argument. The net
result is producing a new base class object whose members correspond to the
base class portion of the derived object.
.12:Why is it usually better to pass objects by reference than by value?
A:Passing an object by reference instead of by value enables the function to
avail itself of virtual functions. Also, passing an object by reference instead of
value may use less memory and time, particularly for large objects. The main
advantage of passing by value is that it protects the original data, but you can
accomplish the same end by passing the reference as a const type.
.13:Suppose Corporation is a base class and PublicCorporation is a derived
class. Also suppose that each class defines a head() member function, that
ph is a pointer to the Corporation type, and that ph is assigned the address
of a PublicCorporation object. How is ph->head() interpreted if the base
class defines head() as a
Regular nonvirtual methoda.
Virtual methodb.
A:If head() is a regular method, then ph->head() invokes Corporation::head().
If head() is a virtual function, then ph->head() invokes
PublicCorporation::head().
.14:What's wrong, if anything, with the following code?
This document was created by an unregistered ChmMagic, please go to to register it. Thanks.
class Kitchen
{
private:

double kit_sq_ft;
public:
Kitchen() { kit_sq_ft = 0.0; }
virtual double area() { return kit_sq_ft * kit_sq_ft; }
};
class House : public Kitchen
{
private:
double all_sq_ft;
public:
House() { all_sq_ft += kit_sq_ft;}
double area(const char *s) { cout << s; return all_sq_ft; }
};
A:
First, the situation does not fit the is-a model, so public inheritance is not
appropriate. Second, the definition of area() in House hides the Kitchen
version of area() because the two methods have different signatures.
Chapter 14
.1:For each of the following sets of classes, indicate whether public or private
derivation is more appropriate for the second column:
class Bearclass PolarBear
class Kitchenclass Home
class Personclass Programmer
class Personclass HorseAndJockey
class Person, class Automobileclass Driver
This document was created by an unregistered ChmMagic, please go to to register it. Thanks.
A:

class Bearclass PolarBear
Public, a polar bear is a kind of bear

class
Kitchen
class Home
Private, a home has a kitchen
class
Person
class Programmer
Public, a programmer is a kind of person
class
Person
class
HorseAndJockey
Private, a horse and jockey team contains
aperson
class
Person,
class
class Driver
Automobile
Person public because a driver is a
person; Automobile private because a
driver has an automobile
.2:Suppose we have the following definitions:
class Frabjous {
private:
char fab[20];
public:
Frabjous(const char * s = "C++") : fab(s) {}
virtual void tell() { cout << fab; }
};

class Gloam {
private:
int glip;
Frabjous fb;
public:
Gloam(int g = 0, const char * s = "C++");
Gloam(int g, const Frabjous & f);
void tell();
};
Given that the Gloam version of tell() should display the values of glip and fb,
provide definitions for the three Gloam methods.
This document was created by an unregistered ChmMagic, please go to to register it. Thanks.
A:
Gloam::Gloam(int g, const char * s) : glip(g), fb(s) { }
Gloam::Gloam(int g, const Frabjous & f) : glip(g), fb(f) { }
// note: the above uses the default Frabjous copy constructor
void Gloam::tell()
{
fb.tell();
cout << glip << '\n';
}
.3:Suppose we have the following definitions:
class Frabjous {
private:
char fab[20];
public:
Frabjous(const char * s = "C++") : fab(s) {}
virtual void tell() { cout << fab; }
};
class Gloam : private Frabjous{

private:
int glip;
public:
Gloam(int g = 0, const char * s = "C++");
Gloam(int g, const Frabjous & f);
void tell();
};
Given that the Gloam version of tell() should display the values of glip and fab,
provide definitions for the three Gloam methods.
A:
Gloam::Gloam(int g, const char * s)
: glip(g), Frabjous(s) { }
Gloam::Gloam(int g, const Frabjous & f)
This document was created by an unregistered ChmMagic, please go to to register it. Thanks.
: glip(g), Frabjous(f) { }
// note: the above uses the default Frabjous copy constructor
void Gloam::tell()
{
Frabjous::tell();
cout << glip << '\n';
}
.4:Suppose we have the following definition, based on the Stack template of
Listing 14.14 and the Worker class of Listing 14.11:
Stack<Worker *> sw;
Write out the class declaration that will be generated. Just do the class
declaration, not the non-inline class methods.
A:
class Stack<Worker *>
{
private:

enum {MAX = 10}; // constant specific to class
Worker * items[MAX]; // holds stack items
int top; // index for top stack item
public:
Stack();
Boolean isempty();
Boolean isfull();
Boolean push(const Worker * & item); // add item to stack
Boolean pop(Worker * & item); // pop top into item
};
.5:Use the template definitions in this chapter to define the following:
An array of String objects
This document was created by an unregistered ChmMagic, please go to to register it. Thanks.
A stack of arrays of double
An array of stacks of pointers to Worker objects
How many template class definitions are produced in Listing 14.19?
A:
ArrayTP<String> sa;
StackTP< ArrayTP<double> > stck_arr_db;
ArrayTp< StackTP<Worker *> > arr_stk_wpr;
.6:Describe the differences between virtual and nonvirtual base classes.
A:If two lines of inheritance for a class share a common ancestor, the class winds
up with two copies of the ancestor's members. Making the ancestor class a
virtual base class to its immediate descendants solves that problem.
Chapter 15
.1:What's wrong with the following attempts at establishing friends?
class snap {
friend clasp;

} ;

class clasp { } ;
a.
class cuff {
public:
void snip(muff &) { }

} ;
class muff {
friend void cuff::snip(muff &);

b.
This document was created by an unregistered ChmMagic, please go to to register it. Thanks.
} ;
class muff {
friend void cuff::snip(muff &);

} ;
class cuff {
public:
void snip(muff &) { }

} ;
c.
A:
The friend declaration should be as follows:
friend class clasp;
a.
This needs a forward declaration so that the compiler can interpret void
snip(muff &):
class muff; // forward declaration

class cuff {
public:
void snip(muff &) { }

};
class muff {
friend void cuff::snip(muff &);

};
b.
First, the cuff class declaration should precede the muff class so that
the compiler can understand the term cuff::snip(). Second, the compiler
needs a forward declaration of muff so that it can understand snip(muff
&).
c.
This document was created by an unregistered ChmMagic, please go to to register it. Thanks.
class muff; // forward declaration
class cuff {
public:
void snip(muff &) { }

};
class muff {
friend void cuff::snip(muff &);

};
.2:You've seen how to create mutual class friends. Can you create a more
restricted form of friendship in which only some members of class B are friends
to class A and some members of A are friends to B? Explain.
A:No. For A to have a friend that's a member function of B, the B declaration must

precede the A declaration. A forward declaration is not enough, for it would tell
A that B is a class, but it wouldn't reveal the names of the class members.
Similarly, if B has a friend that's a member function of A, the complete A
declaration must precede the B declaration. These two requirements are
mutually exclusive.
.3:What problems might the following nested class declaration have?
class Ribs
{
private:
class Sauce
{
int soy;
int sugar;
public:
Sauce(int s1, int s2) : soy(s1), sugar(s2) { }
} ;

This document was created by an unregistered ChmMagic, please go to to register it. Thanks.
} ;
A:The only access to a class is through its public interface, which means the only
thing you can do with a Sauce object is call the constructor to create one. The
other members (soy and sugar) are private by default.
.4:How does throw differ from return?
A:Suppose function f1() calls function f2(). A return statement in f2() causes
program execution to resume at the next statement following the f2() function
call in function f1(). A throw statement causes the program to back up through
the current sequence of function calls until it finds a try block that directly or
indirectly contains the call to f2(). This might be in f1() or in a function that
called f1(), and so on. Once there, execution goes to the next matching catch
block, not to the first statement after the function call.

.5:Suppose you have a hierarchy of exception classes derived from a base
exception class. In what order should you place catch blocks?
A:You should arrange the catch blocks in the order of most derived class to least
derived.
.6:Consider the Grand, Superb, and Magnificent classes defined in this chapter.
Suppose pg is a type Grand * pointer assigned the address of an object of one
of these three classes and that ps is a type Superb * pointer. What is the
difference in how the following two code samples behave?
if (ps = dynamic_cast<Superb *>(pg))
ps->say(); // sample #1
if (typeid(*pg) == typeid(Superb))
(Superb *) pg)->say(); // sample #2
A:For sample #1, the if condition is true if pg points to a Superb object or to an
object of any class descended from Superb. In particular, it is also true if pg
points to a Magnificent object. In sample #2, the if condition is true only for a
Superb object, not for objects derived from Superb.
This document was created by an unregistered ChmMagic, please go to to register it. Thanks.
.7:How is the static_cast operator different from the dynamic_cast operator?
A:The dynamic_cast operator only allows upcasting in a class hierarchy, while a
static_cast operator allows both upcasting and downcasting. The static_cast
operator also allows conversions from enumeration types to integer types, and
vice versa, and between various numeric types.
Chapter 16
.1:Consider the following class declaration:
class RQ1
{
private:
char * st; // points to C-style string
public:
RQ1() { st = new char [1]; strcpy(st,""); }

RQ1(const char * s)
{st = new char [strlen(s) + 1]; strcpy(st, s); }
RQ1(const RQ1 & rq)
{st = new char [strlen(rq.st) + 1]; strcpy(st, rq.st); }
~RQ1() {delete [] st};
RQ & operator=(const RQ & rq);
// more stuff
};
Convert this to a declaration using a string object instead. What methods
no longer need an explicit definition?
A:
#include <string>
using namespace std;
class RQ1
{
private:
This document was created by an unregistered ChmMagic, please go to to register it. Thanks.
string st; // a string object
public:
RQ1() : st("") {}
RQ1(const char * s) : st(s) {}
~RQ1() {};
// more stuff
};
The explicit copy constructor, destructor, and assignment operator no
longer are needed because the string object provides its own memory
management.
.2:Name at least two advantages string objects have over C-style strings in
terms of ease-of-use.
A:You can assign one string object to another. A string object provides its

own memory management so that you normally don't have to worry about a
string exceeding the capacity of its holder.
.3:Write a function that takes a reference to a string as an argument and
which converts the string to all uppercase.
A:
#include <string>
#include <cctype>
using namespace std;
void ToUpper(string & str)
{
for (int i = 0; i < str.size(); i++)
str[i] = toupper(str[i]);
}
.4:Which of the following are not examples of correct usage (conceptually or
syntactically) of auto_ptr? (Assume the needed header files have been
included.)
This document was created by an unregistered ChmMagic, please go to to register it. Thanks.
auto_ptr<int> pia(new int[20]);
auto_ptr<str> (new string);
int rigue = 7;
auto_ptr<int>pr(&rigue);
auto_ptr dbl (new double);
A:
auto_ptr<int> pia= new int[20]; // wrong, use with new, not new[]
auto_ptr<str>(new string); // wrong, no name for pointer
int rigue = 7;
auto_ptr<int>(&rigue); // wrong, memory not allocated by new
auto_ptr dbl (new double); // wrong, omits <double>
.5:If you could make the mechanical equivalent of a stack that held golf clubs
instead of numbers, why would it (conceptually) be a bad golf bag?

A:The LIFO aspect of a stack means you might have to remove a lot of clubs
before reaching the one you need.
.6:Why would a set container be a poor choice for storing a hole-by-hole
record of your golf scores?
A:The set will store just one copy of each value, so, say, five scores of 5
would be stored as a single 5.
.7:Because a pointer is an iterator, why didn't the STL designers simply use
pointers instead of iterators?
A:Using iterators allows one to use objects with a pointer-like interface to
move through data organized in fashions other than an array; for example,
data in a doubly linked list.
.8:Why didn't the STL designers simply define a base iterator class, use
inheritance to derive classes for the other iterator types, and express the
algorithms in terms of those iterator classes?
This document was created by an unregistered ChmMagic, please go to to register it. Thanks.
A:The STL approach lets STL functions be used with ordinary pointers to
ordinary arrays as well as with iterators to STL container classes, thus
increasing generality.
.9:Give at least three examples of convenience advantages that a vector
object has over an ordinary array.
A:You can assign one vector object to another. A vector manages its own
memory, so you can insert items into a vector and have it resize itself
automatically. By using the at() method, you can get automatic bounds
checking.
.10:If Listing 16.6 were implemented with list instead of vector, what parts of
the program would become invalid? Could the invalid part be fixed easily?
If so, how?
A:The two sort() functions and the random_shuffle() function require a
random-access iterator, while a list object just has a bidirectional iterator.
You can use the list template class sort() member functions instead of the

general purpose functions to do the sorting, but there is no member
function equivalent to random_shuffle(). However, you could copy the list
to a vector, shuffle the vector, and copy the results back to the list. (At the
time of this writing, most compilers have not yet implemented the sort()
member function that takes a Compare object as its argument. Also, the
Microsoft Visual C++ 6.0 implementation of the list class has some bugs
that prevent making the suggested conversions.
Chapter 17
.1:What role does the iostream file play in C++ I/O?
A:The iostream file defines the classes, constants, and manipulators used to
manage input and output. These objects manage the streams and buffers
used to handle I/O. The file also creates standard objects (cin, cout, cerr,
and clog and their wide-character equivalents) used to handle the standard
This document was created by an unregistered ChmMagic, please go to to register it. Thanks.
input and output streams connected to every program.
.2:Why does typing a number such as 121 as input require a program to
make a conversion?
A:Keyboard entry generates a series of characters. Typing 121 generates
three characters, each represented by a 1-byte binary code. If the value is
to be stored as type int, these three characters have to be converted to a
single binary representation of the value 121.
.3:What's the difference between the standard output and the standard error?
A:By default, both the standard output and the standard error send output to
the standard output device, typically a monitor. If you have the operating
system redirect output to a file, however, the standard output connects to
the file instead of to the screen, but the standard error continues to be
connected to the screen.
.4:Why is cout able to display various C++ types without being provided
explicit instructions for each type?
A:The ostream class defines a version of the operator<<() function for each

basic C++ type. The compiler interprets an expression like
cout << spot
as the following:
cout.operator<<(spot)
It then can match this method call to the function prototype having the
same argument type.
.5:What feature of the output method definitions allows you to concatenate
output?
A:You can concatenate output methods that return type ostream &. This
causes the invoking of a method with an object to return that object. The
This document was created by an unregistered ChmMagic, please go to to register it. Thanks.
returned object can then invoke the next method in a sequence.
.6:Write a program that requests an integer and then displays it in decimal,
octal, and hexadecimal form. Display each form on the same line in fields
that are 15 characters wide, and use the C++ number base prefixes.
A:
//rq17-6.cpp
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
cout << "Enter an integer: ";
int n;
cin >> n;
cout << setw(15) << "base ten" << setw(15)
<< "base sixteen" << setw(15) << "base eight" << "\n";
cout.setf(ios::showbase); // or cout << showbase;
cout << setw(15) << n << hex << setw(15) << n
<< oct << setw(15) << n << "\n";

return 0;
}
.7:Write a program that requests the information shown below and that
formats it as shown:
Enter your name: Billy Gruff
Enter your hourly wages: 12
Enter number of hours worked: 7.5
First format:
Billy Gruff: $ 12.00: 7.5
Second format:
Billy Gruff : $12.00 :7.5
This document was created by an unregistered ChmMagic, please go to to register it. Thanks.
A:
//rq17-7.cpp
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
char name[20];
float hourly;
float hours;
cout << "Enter your name: ";
cin.get(name, 20).get();
cout << "Enter your hourly wages: ";
cin >> hourly;
cout << "Enter number of hours worked: ";
cin >> hours;
cout.setf(ios::showpoint);
cout.setf(ios::fixed, ios::floatfield);

cout.setf(ios::right, ios::adjustfield);
// or cout << showpoint << fixed << right;
cout << "First format:\n";
cout << setw(30) << name << ": $" << setprecision(2)
<< setw(10) << hourly << ":" << setprecision(1)
<< setw(5) << hours << "\n";
cout << "Second format:\n";
cout.setf(ios::left, ios::adjustfield);
cout << setw(30) << name << ": $" << setprecision(2)
<< setw(10) << hourly << ":" << setprecision(1)
<< setw(5) << hours << "\n";
return 0;
}
.8:Consider the following program:
//rq17-8.cpp
This document was created by an unregistered ChmMagic, please go to to register it. Thanks.

Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Tải bản đầy đủ ngay
×