U E D R S I H C RSS
ID
Password
Join
열정이 μ—†λŠ” 인생은 μžμœ κ°€ μ—†λŠ” 인생과도 κ°™λ‹€. -- μ•€ν„°λ‹ˆ ν€Έ

ο»Ώ * 원문링크 : [http]http://www.cplusplus.com/doc/tutorial/tut5-4.html

Contents

1 κ°œμš”
2 reinterpret_cast
3 static_cast
4 dynamic_cast
5 const_cast
6 typeid

1 κ°œμš” #

Until now, in order to type-cast a simple object to another we have used the traditional type casting operator. For example, to cast a floating point number of type double to an integer of type int we have used:

int i;
double d;
i = (int) d;

or also

i = int (d);

This is quite good for basic types that have standard defined conversions, however this operators can also be indiscriminately applied on classes and pointers to classes. So, it is perfectly valid to write things like:
// class type-casting
#include <iostream.h>

class CDummy {
    int i;
};

class CAddition {
	int x,y;
  public:
	CAddition (int a, int b) { x=a; y=b; }
	int result() { return x+y;}
};

int main () {
  CDummy d;
  CAddition * padd;
  padd = (CAddition*) &d;
  cout << padd->result();
  return 0;
}

Although the previous program in sintactically correct in C++ (in fact it will compile with no warnings on most compilers) it is code with not much sense since we use function result, that is a member of CAddition, without having declared an object of that class: padd is not an object, it is only a pointer which we have assigned the address of a non related object. When accessing its result member it will produce a run-time error or, at best, just an unexpected result.

In order to control these types of conversions between classes, ANSI-C++ standard has defined four new casting operators: reinterpret_cast, static_cast, dynamic_cast and const_cast. All of them have the same format when used:

reinterpret_cast <new_type> (expression)
    dynamic_cast <new_type> (expression)
     static_cast <new_type> (expression)
      const_cast <new_type> (expression)

Where new_type is the destination type to which expression has to be casted. To make an easily understandable parallelism with traditional type-casting operators these expression mean:

(new_type) expression
new_type (expression)

but with their own special characteristics.

2 reinterpret_cast #

reinterpret_cast은 포인터 νƒ€μž…μ„ λ‹€λ₯Έ νƒ€μž…μ˜ 포인터 νƒ€μž…μœΌλ‘œ ν˜•λ³€ν™˜ν•˜λŠ”λ° μ‚¬μš©ν•©λ‹ˆλ‹€. λ˜ν•œ 포인터λ₯Ό int νƒ€μž…μœΌλ‘œ ν˜•λ³€ν™˜ν•˜λŠ”κ±°λ‚˜ κ·Έ λ°˜λŒ€λ„ κ°€λŠ₯ν•©λ‹ˆλ‹€. 이 λͺ…령은 μ„œλ‘œ 관련이 μ—†λŠ” 두 클래슀 ν¬μΈν„°κ°„μ˜ ν˜•λ³€ν™˜μ„ κ°€λŠ₯ν•˜κ²Œ ν•©λ‹ˆλ‹€. μ‹€ν–‰ κ²°κ³ΌλŠ” ν•œ ν¬μΈν„°μ—μ„œ λ‹€λ₯Έ 포인터에 λŒ€ν•œ 값에 λŒ€ν•œ κ°„λ‹¨ν•œ 이진 λ³΅μ‚¬λ³Έμž…λ‹ˆλ‹€. μƒν˜Έ νƒ€μž…κ°„ λ³€ν™˜μ€‘μ—λŠ” μ–΄λ– ν•œ μ’…λ₯˜μ˜ κ²€μ‚¬λ‚˜ λ³€ν™˜μ΄ μΌμ–΄λ‚˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

ν¬μΈν„°μ—μ„œ int둜 λ³€ν™˜λ˜λŠ” κ²½μš°μ—λŠ”, λ²ˆμ—­λ˜λŠ” 방법은 μ‹œμŠ€ν…œμ— 따라 λ‹€λ₯΄λ©°, κ·ΈλŸ¬λ―€λ‘œ λͺ¨λ“  κ΅¬ν˜„μ΄ 이식가λŠ₯ν•œ 것은 μ•„λ‹™λ‹ˆλ‹€. intν˜•μ΄ 포인터값을 담기에 μΆ©λΆ„νžˆ 큰 λ°”μ΄νŠΈμˆ˜λ₯Ό κ°€μ§€κ³  μžˆμ–΄μ•Όλ§Œ λ‚˜μ€‘μ— 포인터 κ°’μœΌλ‘œ λ‹€μ‹œ ν˜•λ³€ν™˜ν•˜λŠ” 것이 κ°€λŠ₯ν•©λ‹ˆλ‹€. (일반적으둜, 16λΉ„νŠΈμ‹œμŠ€ν…œμ΄λ‚˜ λͺ‡λͺ‡ PDA, μ‹€μ‹œκ°„μš΄μ˜μ²΄κ³„λ₯Ό μ œμ™Έν•œ PCλ‚˜ μ„œλ²„κΈ‰μ—μ„œλŠ” μ•ˆμ „ν•©λ‹ˆλ‹€.)

class A {};
class B {};
A * a = new A;
B * b = reinterpret_cast<B*>(a);

reinterpret_cast은 전톡적인 νƒ€μž… ν˜•λ³€ν™˜ μ—°μ‚°μžμ™€ 같이 λͺ¨λ“  포인터에 λŒ€ν•œ ν˜•λ³€ν™˜μ„ μ •ν™•ν•˜κ²Œ μ²˜λ¦¬ν•©λ‹ˆλ‹€.

3 static_cast #

static_cast performs any casting that can be implicitly performed as well as the inverse cast (even if this is not allowed implicitly). Applied to pointers to classes, that is to say that it allows to cast a pointer of a derived class to its base class (this is a valid conversion that can be implicitly performed) and it can also perform the inverse: cast a base class to its derivated class.

In this last case the base class that is being casted is not checked to determine wether this is a complete class of the destination type or not.
class Base {};
class Derived: public Base {};
Base * a = new Base;
Derived * b = static_cast<Derived*>(a);
static_cast, aside from manipulating pointers to classes, can also be used to perform conversions explicitly defined in classes, as well as to perform standard conversions between fundamental types:
double d=3.14159265;
int i = static_cast<int>(d); 

4 dynamic_cast #

dynamic_cast is exclusively used with pointers and references to objects. It allows any type-casting that can be implicitly performed as well as the inverse one when used with polymorphic classes, however, unlike static_cast, dynamic_cast checks, in this last case, if the operation is valid. That is to say, it checks if the casting is going to return a valid complete object of the requested type. Checking is performed during run-time execution. If the pointer being casted is not a pointer to a valid complete object of the requested type, the value returned is a NULL pointer.

class Base { virtual dummy(){}; };
class Derived : public Base { };
 
Base* b1 = new Derived;
Base* b2 = new Base;
Derived* d1 = dynamic_cast<Derived*>(b1);   // succeeds
Derived* d2 = dynamic_cast<Derived*>(b2);   // fails: returns NULL

If the type-casting is performed to a reference type and this casting is not possible an exception of type bad_cast is thrown:

class Base { virtual dummy(){}; };
class Derived : public Base { };
 
Base* b1 = new Derived;
Base* b2 = new Base;
Derived d1 = dynamic_cast<Derived&*>(b1);   // succeeds
Derived d2 = dynamic_cast<Derived&*>(b2);   // fails: exception thrown

5 const_cast #

This type of casting manipulates the const attribute of the passed object, either to be set or removed:
class C {};
const C * a = new C;
C * b = const_cast<C*> (a);

Neither of the other three new cast operators can modify the constness of an object.

6 typeid #

ANSI-C++ also defines a new operator called typeid that allows checking the type of an expression:
typeid (expression)

this operator returns a refernece to a constant object of type type_info that is defined in the standard header file <typeinfo>. This returned value can be compared with another using operators == and != or can serve to obtain a string of characters representing the data type or class name by using its name() method.

// typeid, typeinfo
#include <iostream.h>
#include <typeinfo>

class CDummy { };

int main () {
  CDummy* a,b;
  if (typeid(a) != typeid(b))
  {
    cout << "a and b are of different types:\n";
    cout << "a is: " << typeid(a).name() << '\n';
    cout << "b is: " << typeid(b).name() << '\n';
  }
  return 0;
}
a and b are of different types:
a is: class CDummy *
b is: class CDummy 

Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2010-10-28 12:42:52
Processing time 0.3278 sec