Trang

Thursday, June 12, 2014

static_cast C++

Casting
Casting là cách chuyển đổi kiểu dữ liệu theo mong muốn của lập trình viên. Trong chương trình C chuẩn, Cast được thực hiện thông qua toán tử (), với tên của loại dữ liệu muốn cast ở bên trong. Ví dụ
int nValue1 = 10;

int nValue2 = 4 ;

float fValue = (float)nValue1 / nValue2 ;
Trong chương trình ở trên, chúng ta sử dụng float cast để báo cho trình biên dịch biết để thằng cấp nValue1 thành kiểu float. Bởi vì nValue1 có kiểu float nên nValue2 sau đó cũng được chuyển đổi thành kiểu float. Và khi đó, phép chia là phép chia kiểu số thực(float) thay vì số nguyên (integer)
C++ cũng sẻ cho bạn sử dụng kiểu C cast này trong chương trình C++ của bạn :
int nValue1 = 10;

int nValue2 = 4 ;

float fValue = (float)nValue1 / nValue2 ;
C++ giới thiệu một toán tử casting mới gọi là static_cast. Static cast làm việc tương tự như kiểu C cast.
int nValue1 = 10;

int nValue2 = 4 ;

float fValue = static_cast(nValue1) / nValue2 ;
Bạn nên tránh sử dụng casting trong tất cả mọi trường hợp nếu có thể, bởi vì bất kì ở đâu sử dụng cast, ở đó có thể là nguyên nhân gây ra nhiều vấn đề cho chương trình của bạn. Nhưng đôi khi bạn bắt buộc phải sử dụng nếu không thể tránh được. Trong trường hợp này, trong C++ bạn nên sử dụng static_cast thay vì S-style cast :d

Để có thể điều khiển việc chuyển đổi kiểu giữa các lớp, chuẩn ANSI-C++ đã định nghĩa bốn toán tử chuyển đổi kiểu mới: reinterpret_caststatic_castdynamic_cast và const_cast. Tất cả chúng đều có cùng dạng thức khi sử dụng:
reinterpret_cast <new_type> (expression)
    dynamic_cast <new_type> (expression)
     static_cast <new_type> (expression)
      const_cast <new_type> (expression)
Trong đó new_type kiểu mà expression phải được chuyển đổi thành. Để tạo ra sự tương tự dễ hiểu với các toán tử chuyển đổi truyền thống các biểu thức này có nghĩa là:
(new_type) expression
new_type (expression)

reinterpret_cast

reinterpret_cast chuyển đổi một con trỏ sang bất kì kiểu con trỏ nào khác. Nó cũng cho phép chuyển đổi từ con trỏ sang dạng số nguyên và ngược lại.
Toán tử này có thể chuyển đổi con trỏ giữa các lớp không có quan hệ với nhau. Kết quả của toán tử này là một bản copy giá trị của con trỏ này sang con trỏ kia. Dữ liệu được trỏ đến không hề được kiểm tra hay chuyển đổi.
Trong trường hợp chuyển đổi giữa con trỏ và số nguyên, cách chuyển nội dung của nó phụ thuộc vào hệ thống. 
class A {};
class B {};
A * a = new A;
B * b = reinterpret_cast(a);
reinterpret_cast đối xử với tất cả các con trỏ giống như các toán tử chuyển đổi truyền thống.

static_cast

static_cast cho phép thực hiện bất kì phép chuyển đổi nào
static_cast allows to perform any casting that can be implicitly performed as well as also 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 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(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(d);

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_castdynamic_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(b1);   // succeeds
Derived* d2 = dynamic_cast(b2);   // fails: returns NULL
If the type-casting is performed to a reference type and this casting is not possible an exception of typebad_cast is thrown:
class Base { virtual dummy(){}; };
class Derived : public Base { };
 
Base* b1 = new Derived;
Base* b2 = new Base;
Derived d1 = dynamic_cast(b1);   // succeeds
Derived d2 = dynamic_cast(b2);   // fails: exception thrown

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 (a);
Neither of the other three new cast operators can modify the constness of an object.

typeid

ANSI-C++ also defines a new operator called typeid that allows to check the type of an expression:
typeid (expression)
this operator returns a refernece to a constant object of type type_info that is defined in standard header file . 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.


static_cast: chuyển kiểu dữ liệu bình thường như int -> char,...
dynamic_cast: chuyển đổi kiểu con trỏ (hoặc kiểu tham chiếu) giữa các lớp đa hình trong đa kế thừa.
reinterpret_cast: chuyển đổi giữa 2 kiểu dữ liệu ko có mối liên hệ, vd như là int -> pointer,...
const_cast: bỏ const ra khỏi dữ liệu được chuyển đổi.

2 comments:

  1. Chà học cái này mà ra đầu tư thì okê y như rằng !

    Em nhớ hum bữa cũng làm cái kia mà ra thanh công không thế
    Kỷ niệm đó hay ghê ta

    Click vào đây nhé : Bán Căn Hộ Sunview Town quận Thủ Đức tại TPHCM hoặc click vào đây nhé bạn ban can ho sunview town quan thu duc tai tphcm

    ReplyDelete