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
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]