Siêu thị PDFTải ngay đi em, trời tối mất

Thư viện tri thức trực tuyến

Kho tài liệu với 50,000+ tài liệu học thuật

© 2023 Siêu thị PDF - Kho tài liệu học thuật hàng đầu Việt Nam

ANSI/ISO C++ Professional Programmer''''s Handbook phần 2 potx
MIỄN PHÍ
Số trang
21
Kích thước
62.5 KB
Định dạng
PDF
Lượt xem
1879

ANSI/ISO C++ Professional Programmer''''s Handbook phần 2 potx

Nội dung xem thử

Mô tả chi tiết

long n = 1000000L; long *pl = &n;

unsigned char * pc = reinterpret_cast <unsigned char *> (pl);

printf("%d %d %d %d", pc[0], pc[1], pc[2], pc[3]); //memory dump

}

reinterpret_cast can cast integers to pointers, and vice versa. For example

void *pv = reinterpret_cast<void *> (0x00fffd);

int ptr = reinterpret_cast<int> (pv);

reinterpret_cast can also be used for conversions between different types of function pointers. The result of

using the resultant pointer to call a function with a nonmatching type is undefined.

Do not use reinterpret_cast instead of static_cast -- the results might be undefined. For example, using

reinterpret_cast to navigate through the class hierarchy of a multiply-inherited object is likely to yield the

wrong result. Consider the following:

class A

{

private:

int n;

};

class B

{

private:

char c;

};

class C: public A, public B

{};

void func(B * pb)

{

C *pc1 = static_cast<C*> (pb); //correct offset adjustment

C *pc2 = reinterpret_cast<C*> (pb); //no offset calculated

}

int main()

{

B b;

func(&b);

}

On my machine, pc1 is assigned the value 0x0064fdf0, whereas pc2 is assigned 0x0064fdf4. This

demonstrates the difference between the two cast operators. Using the information that is available at compile time,

static_cast converts a pointer to B to a pointer to C. It does so by causing pc1 to point at the start of C by

subtracting the offset of the subobject B. On the other hand, reinterpret_cast simply assigns the binary value

of pb to pc2, without any further adjustments; for this reason, it yields the wrong result.

dynamic_cast

In pre-standard C++, as was noted earlier, C-style cast was used to perform a dynamic cast as well. The cast was

either static or dynamic, depending on the type of the operand. The Standardization committee, however, opposed this

approach. An expensive runtime operation that looked exactly like a static cast (that is, penalty-free) can mislead the

users. For this purpose, a new operator was introduced to the language: dynamic_cast (dynamic_cast is

ANSI/ISO C++ Professional Programmer's Handbook - Chapter 2 - Standard Briefing: The Latest Addenda to ANSI/ISO C++

file:///D|/Cool Stuff/old/ftp/1/1/ch02/ch02.htm (11 von 24) [12.05.2000 14:45:45]

discussed in further detail in Chapter 7, "Runtime Type Identification"). The name and the syntax of

dynamic_cast were chosen to look markedly different from C-style cast. All other new typecast operators follow

this model. Following is an example of dynamic_cast:

Derived *p = dynamic_cast<derived *> (&base); //pointer form

Derived & rd = dynamic_cast<derived &> (base); //reference form

Conclusions

The new typecasting operators are clearer and more explicit in their intended purpose. A name such as

dynamic_cast, for example, warns its users about its incurred runtime overhead. Most importantly, though, the

new cast operators are safer because they give the compiler a chance to detect the programmer's mistakes.

Users might find the proliferation of cast operators somewhat confusing. In particular, the choice between

static_cast and reinterpret_cast might not seem immediately clear. How to choose? As a rule,

static_cast is the first choice. If the compiler refuses to accept it, use reinterpret_cast instead.

Built-in bool Type

The built-in bool data type was added to the Standard after consideration of several other proposals. None of these

was found satisfactory. Following is an overview some of these proposals, which is in turn followed by a discussion

of the characteristics of the bool type.

typedef Boolean

One suggestion was to use a typedef for a Boolean data type:

typedef int bool;

However, a typedef that relies on another built-in type of the language renders the Boolean type unusable with

some language features. For example, using it in function overloading can result in ambiguities:

void f(bool);

void f(int);//error, redefinition of void f(bool);

In addition, a typedef is not strongly-typed. Consequently, it is impossible to ensure that only Boolean values are

assigned to it in a context that requires Boolean values.

enum Type

An alternative solution was to use an enum type:

enum bool { false, true};

enums are strongly-typed. However, the committee wanted to ensure backward compatibility with old code that used

int values as a Boolean data type. For example

#include <ctype.h>

enum bool {false, true};

void f()

{

enum bool b;

ANSI/ISO C++ Professional Programmer's Handbook - Chapter 2 - Standard Briefing: The Latest Addenda to ANSI/ISO C++

file:///D|/Cool Stuff/old/ftp/1/1/ch02/ch02.htm (12 von 24) [12.05.2000 14:45:45]

Tải ngay đi em, còn do dự, trời tối mất!