1. Trang chủ
  2. » Công Nghệ Thông Tin

C++ Primer Plus (P54) doc

20 262 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 20
Dung lượng 267,53 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

The dynamic_cast operator is used to cast a derived class pointer to a base class pointer; its main purpose is to ensure that it's okay to invoke a virtual function call.. .5: Suppose yo

Trang 1

compiler to accept the following statement in change():

*pc = 100;

However, because pop2 is declared as const, the compiler may protect it from any

change, as is shown by the following sample output:

pop1, pop2: 38383, 2000

pop1, pop2: 100, 2000

As you can see, the calls to change() altered pop1 but not pop2 (The particular compiler

used here generated a temporary copy of pop2 and assigned that address to pc, but, as

mentioned, the standard says the behavior in this situation is undefined.)

The static_cast operator has the same syntax as the others:

static_cast < type-name > (expression)

It's valid only if type_name can be converted implicitly to the same type expression has,

or vice versa Otherwise, the cast is an error Suppose High is a base class to Low and

that Pond is an unrelated class Then conversions from High to Low and Low to High are

valid, but a conversion from Low to Pond is disallowed:

High bar;

Low blow;

High * pb = static_cast<High *> (&blow); // valid upcast

Low * pl = static_cast<Low *> (&bar); // valid downcast

Pond * pmer = static_cast<Pond *> (&blow); // invalid, Pond unrelated

The first conversion is valid because an upcast can be done explicitly The second

conversion, from a base-class pointer to a derived-class pointer can't be done without an

explicit type conversion But because the type cast in the other direction can be made

without a type cast, it's valid to use a static_cast for a downcast

Similarly, because an enumeration value can be converted to an integral type without a

type cast, an integral type can be converted to an enumeration value with static_cast

Similarly, you can use static_cast to convert double to int, float to long, and the various

This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it Thanks

Trang 2

other numeric conversions.

The reinterpret_cast operator is for inherently risky type-casts It won't let you cast away

const, but it will do other unsavory things Sometimes a programmer has to do

implementation-dependent, unsavory things, and using the reinterpret_cast operator

makes it simpler to keep track of such acts It has the same syntax as the other three:

reinterpret_cast < type-name > (expression)

Here is a sample use:

struct dat { short a; short b} ;

long value = 0xA224B118;

dat * pd = reinterpret_cast< dat *) (&value);

cout << pd->a; // display first 2 bytes of value

Typically, such casts would be used for low-level, implementation-dependent programming

and would not be portable For example, this code sample produces different output on an

IBM-compatible than it does on a Macintosh because the two systems store the bytes in

multibyte integer types in opposite orders

Summary

Friends allow you to develop a more flexible interface for classes A class can have other

functions, other classes, and member functions of other classes as friends In some cases,

you may need to use forward declarations and to exert care in the ordering of class

declarations and methods in order to get friends to mesh properly

Nested classes are classes declared within other classes Nested classes facilitate the

design of helper classes that implement other classes but needn't be part of a public

interface

The C++ exception mechanism provides a flexible way to deal with awkward programming

events such as inappropriate values, failed I/O attempts, and the like Throwing an

exception terminates the function currently executing and transfers control to a matching

catch block Catch blocks immediately follow a try block, and for an exception to be caught,

the function call that directly or indirectly led to the exception must be in the try block The

program thenexecutes the code in the catch block This code may attempt to fix the

Trang 3

problem or it can terminate the program A class can be designed with nested exception

classes that can be thrown when problems specific to the class are detected A function

can include an exception specification identifying those exceptions that can be thrown in

that function Uncaught exceptions (those with no matching catch block) by default,

terminate a program So do unexpected exceptions (those not matching an exception

specification.)

The RTTI (runtime type information) features allow a program to detect the type of an

object The dynamic_cast operator is used to cast a derived class pointer to a base class

pointer; its main purpose is to ensure that it's okay to invoke a virtual function call The

typeid operator returns a type_info object Two typeid return values can be compared to

determine if an object is of a specific type, and the returned type_info object can be used

to obtain information about an object

The dynamic_cast operator, along with static_cast, const_cast, and reinterpret_cast,

provide safer, better-documented type casts than the general cast mechanism

Review Questions

.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 http://www.bisenter.com to register it Thanks

Trang 4

} ;

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

} ; class cuff { public:

void snip(muff &) { } .

} ;

c.

.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

.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) { } } ;

.

} ; 4: How does throw differ from return?

.5: Suppose you have a hierarchy of exception classes derived from a base exception class In what order should you place catch blocks?

Trang 5

.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 7: How is the static_cast operator different from the dynamic_cast operator?

Programming Exercises

1: Modify the Tv and Remote classes as follows:

Make them mutual friends

a.

Add a state variable member to the Remote class that describes whether the remote control is in normal or interactive mode

b.

Add a Remote method that displays the mode

c.

Provide the Tv class with a method for toggling the new Remote member This method should work only if the Tv is in the on state

d.

Write a short program testing these new features

2: Modify Listing 15.10 so that hmean() throws an exception of type hmeanexcp and gmean() throws an exception of type gmeanexcp Both of these exception types are to be classes derived from the exception class provided by the

<exception> header file, and you should overload the what() method for each new class so that the message displayed by what() reports the function name and the nature of the problem Also, upon catching an hmeanexcp exception, This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it Thanks

Trang 6

the program should prompt for a new data pair and continue with the loop, while upon catching a gmeanexcp exception, the program should break out of the loop and continue with the code following the loop

CONTENTS

Trang 7

Chapter 16 THE string CLASS AND THE

STANDARD TEMPLATE LIBRARY

You will learn about the following in this chapter:

The string Class The auto_ptr Class The Standard Template Library Generic Programming

Function Objects (aka Functors) Algorithms

Other Libraries Summary Review Questions Programming Exercises

By now you are familiar with the C++ goal of reusable code One of the big payoffs is when

you can reuse code written by others That's where class libraries come in There are many

commercially available C++ class libraries, and there also are the libraries that come as

part of the C++ package For example, you've been using the input/output classes

supported by the ostream header file This chapter will look at other reusable code

available for your programming pleasure First, the chapter examines the string class,

which simplifies programming with strings Then it looks at auto_ptr, a "smart pointer"

template class that makes managing dynamic memory a bit easier Finally, it looks at the

Standard Template Library (or STL), a collection of useful templates for handling various

kinds of container objects STL exemplifies a recent programming paradigm called generic

programming

The string Class

Many programming applications need to process strings C provides some support with its

string.h (cstring in C++) family of string functions, and many early C++ implementations

provided home-grown classes to handle strings Chapter 12, "Classes and Dynamic

This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it Thanks

Trang 8

Memory Allocation," introduced a modest String class to illustrate some aspects of class

design ANSI/ISO C++ itself provides a more powerful version called the string class It is

supported by the string header file.(Note that the string.h and cstring header files support

the C library string functions for C-style strings, not the string class.) The key to using a

class is knowing its public interface, and the string class has an extensive set of methods,

including several constructors, overloaded operators for assigning strings, concatenating

strings, comparing strings, and accessing individual elements, as well as utilities for finding

characters and substrings in a string, and more In short, the string class has lots of stuff

Constructing a String

Let's begin with looking at the string constructors After all, one of the most important

things to know about a class is what your options are when creating objects of that class

Listing 16.1 uses all six of the string constructors (labeled ctor, the traditional C++

abbreviation for constructor) Table 16.1 briefly describes the constructors in the order

used in the program The constructor representations are simplified in that they conceal the

fact that string really is a typedef for a template specialization basic_string<char> and

that they omit an optional argument relating to memory management (This aspect is

discussed later this chapter and in Appendix F, "The String Template Class.") The type

size_type is an implementation-dependent integral type defined in the string header file

The class defines string::npos as the maximum possible length of the string Typically,

this would equal the maximum value of an unsigned int Also, the table uses the common

abbreviation NBTS for null-byte-terminated string, that is, the traditional C string, which is

terminated with a null character

Trang 9

Table 16.1 string Class Constructors

string(const char * s) Initializes string object to NBTS pointed to by

s.

string(size_type n, char c) Creates a string object of n elements, each

initialized to the character c.each initialized to the character

string(const string & str, string

size_type pos = 0, size_type n = npos)

Initializes string object to the object str, starting at position pos in str and going to end

of str or using n characters, whichever comes first

string(const char * s, size_type n) Initializes string object to NBTS pointed to by

s and continues for n characters even if that exceeds the size of the NBTS

template<class Iter>

string(Iter begin, Iter end)

Initializes string object to the values in the range [begin, end), where begin and end act like pointers and specify locations; the range includes begin and is up to but not including end

The program also uses the overloaded += operator, which appends one string to another,

the overloaded = operator for assigning one string to another, the overloaded << operator

for displaying a string object, and the overloaded [] operator for accessing an individual

character in a string

// str1.cpp introducing the string class

#include <iostream>

#include <string>

using namespace std;

// using string constructors

This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it Thanks

Trang 10

int main()

{

string one("Lottery Winner!"); // ctor #1

cout << one << endl; // overloaded <<

string two(20, '$'); // ctor #2

cout << two << endl;

string three(one); // ctor #3

cout << three << endl;

one += " Oops!"; // overloaded +=

cout << one << endl;

two = "Sorry! That was ";

three[0] = 'P';

string four; // ctor #4

four = two + three; // overloaded +, =

cout << four << endl;

char alls[] = "All's well that ends well";

string five(alls,20); // ctor #5

cout << five << "!\n";

string six(alls+6, alls + 10); // ctor #6

cout << six << ", ";

string seven(&five[6], &five[10]);// ctor #6 again

cout << seven << " \n";

return 0;

}

Compatibility Note

Some older string implementations do not support ctor #6

Here is the program's output:

Lottery Winner!

$$$$$$$$$$$$$$$$$$$$

Lottery Winner!

Trang 11

Lottery Winner! Oops!

Sorry! That was Pottery Winner!

All's well that ends!

well, well

Program Notes

The start of the program illustrates that you can initialize a string object to a regular C-style

string and display it using the overloaded << operator:

string one("Lottery Winner!"); // ctor #1

cout << one << endl; // overloaded <<

The next constructor initializes the string object two to a string consisting of 20 $

characters:

string two(20, '$'); // ctor #2

The copy constructor initializes the string object three to the string object one:

string three(one); // ctor #3

The overloaded += operator appends the string " Oops!" to the string one:

one += " Oops!"; // overloaded +=

This particular example appends a C-style string to a string object However, the +=

operator is multiply overloaded so that you also can append string objects and single

characters:

one += two; // append a string object (not in program)

one += '!'; // append a type char value (not in program)

Similarly, the = operator is overloaded so that you can assign a string object to a string

object, a C-style string to a string object, or a simple char value to a string object:

two = "Sorry! That was "; // assign a C-style string

This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it Thanks

Ngày đăng: 07/07/2014, 06:20

TỪ KHÓA LIÊN QUAN

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN