Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 7

5 toán tử ép kiểu trong C++

November 2, 2017 VietVH Advanced C/C++ 0

Contents [hide]
 1 Ép kiểu là gì?
 2 static_cast
 3 const_cast

Ép kiểu là gì?
Ép kiểu (Casting) là quá trình convert từ kiểu dữ liệu A sang kiểu dữ liệu B. C++ có 2 kiểu casting.

Implicit conversion: việc ép kiểu được thực hiện tự động bởi compiler.

1
int iVar = 10; float fVar = iVar; //fVar = 10.00
2

Explicit conversion: ép kiểu được thực hiện bởi lập trình viên.

1
int iVar = 20; float fVar = (float)iVar / 10;
2

Ngôn ngữ C++ support 5 toán tử ép kiểu.


– static_cast
– const_cast
– reinterpret_cast
– dynamic_cast

static_cast
static_cast <type-id> ( expression )

Convert expression thành kiểu dữ liệu type-id.

Một số lưu ý khi sử dụng static_cast

– Không có check run-time, do vậy ko đảm bảo an toàn khi sử dụng static_cast trong 1 số
trường hợp.
– static_cast thường được sử dụng ép kiểu từ int –> float, float –> double,…
– Có thể sử dụng static_cast để convert pointer to base-class sang pointer to derived-class
(không khuyến cáo sử dụng cách này, nên sử dụng dynamic_cast)

Ví dụ 1:

5
// static_cast_Operator.cpp
6 // compile with: /LD
class B {};
7 class D : public B {};
void f(B* pb, D* pd)
8 {
D* pd2 = static_cast<D*>(pb); // Not safe, D can have
9 fields // and methods that are not in B.
B* pb2 = static_cast<B*>(pd); // Safe conversion, D
10 always // contains all of B. }

11

12

13

14

Trong ví dụ 1,
– Line B* pb2 = static_cast<B*>(pd); an toàn vì các thuộc tính và method của class B đều thuộc
class D.
– Line D* pd2 = static_cast<D*>(pb); không an toàn vì class D có các thuộc tính và method mà class
B không có. Tuy nhiên, câu lệnh này không báo lỗi khi chạy runtime vì toán tử static_cast không có
check runtime (khác với toán tử dynamic_cast). Điều thực sự nguy hiểm khi sử dụng *pd2 truy cập
tới thuộc tinh và method chỉ thuộc lớp D và không thuộc lớp B –> Chương trình crash do ACCESS
VIOLATION.

Ví dụ 2:

1 // static_cast_Operator_2.cpp
// compile with: /LD /GR
2 class B
{ public:
3 virtual void Test(){}
}; class D : public B {};
4 void f(B* pb)
{
5 D* pd1 = dynamic_cast<D*>(pb);
D* pd2 = static_cast<D*>(pb);
6 }

10

11

12

13

14

Trong ví dụ 2,
– Nếu pb thực sự trỏ tới đối tượng class D, thì pd1 và pd2 sẽ có cùng giá trị, pd1 và pd2 sẽ có cùng
giá trị nếu pd == 0 (NULL).
– Nếu pb trỏ tới đối tượng class B, thì dynamic_static sẽ trả về 0, nhưng static_cast không thể
detect được vấn đề này. Do vậy, trong trường hợp sử dụng static_cast, lập trình viên phải kiểm tra
nếu pb trỏ tới đối tượng class D thì mới trả về con trỏ trỏ tới class D.

Ví dụ 3:

1 // static_cast_Operator_3.cpp
// compile with: /LD /GR
2 typedef unsigned char BYTE;
void f()
{
3
char ch;
int i = 300;
4
float f = 2.5;
double dbl;
5
ch = static_cast<char>(i); // int to char dbl =
6 static_cast<double>(f); // float to double i = static_cast<BYTE>(ch);
}
7

10

11

12

13

14

15

Trong ví dụ 3,
– Toán tửstatic_cast được sử dụng để ép kiểu cho các kiểu dữ basic. Từ int –> char, float –>
double, char –> int.
– Câu lệnh “ch = static_cast(i); // int to char” gây ra mất dữ liệu vì kiểu char (1 byte) không đủ chứa
kiểu int (4 bytes). Do vậy, chỉ ép kiểu từ kiểu dữ liệu NHỎ –> kiểu dữ liệu TO để tránh convert sai.

const_cast
const_cast < type-id > ( expression )

1 // expre_const_cast_Operator.cpp
// compile with: /EHsc
2 #include <iostream> using namespace std; class CCTest
{ public:
void setNumber( int );
3
void printNumber() const; private:
int number;
4
};
void CCTest::setNumber( int num ) { number = num; }
5
void CCTest::printNumber() const
{
6
cout << "\nBefore: " << number;
const_cast< CCTest * >( this )->number--;
7 cout << "\nAfter: " << number;
}
8 int main()
{
9 CCTest X;
X.setNumber( 8 );
10 X.printNumber();
system("pause");
11 }

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30
Toán tử ép kiểu (casting) trong C++

Trang trước
Trang sau

Toán tử ép kiểu (một cast) trong C++ là một toán tử đặc biệt mà làm một kiểu dữ liệu này biến đổi
thành kiểu dữ liệu khác. Toán tử ép kiểu là một toán tử một ngôi và có cùng độ ưu tiên như bất kỳ
toán tử một ngôi nào khác trong C++.

Cú pháp được sử dụng thường xuyên của toán tử ép kiểu trong C++ là:

(kieu_du_lieu) bieu_thuc

Ở đây, kieu_du_lieu là kiểu dữ liệu bạn muốn. Dưới đây là một số toán tử ép kiểu được hỗ trợ bởi
C++:

 const_cast<kieu_du_lieu> (bieu_thuc): Toán tử const_cast được sử dụng để ghi đè const và/hoặc


volatile. Kiểu dữ liệu bạn muốn phải giống như kiểu dữ liệu nguồn ngoại trừ sự sửa đổi của các thuộc
tính const hoặc volatile trong một cast. Dạng ép kiểu này thao tác thuộc tính const của đối tượng đã
truyền: hoặc được thiết lập hoặc gỡ bỏ.
 dynamic_cast<kieu_du_lieu> (bieu_thuc): Toán tử dynamic_cast trong C++ thực hiện một ép kiểu
tại runtime mà thẩm tra tính hợp lệ của cast. Nếu cast không thể được tạo ra, cast này thất bại và biểu
thức ước lượng là null. Một toán tử dynamic_cast thực hiện các cast trên các kiểu đa hình và có thể
ép một con trỏ A* thành một con trỏ B* chỉ khi đối tượng đang được trỏ tới thực sự là một đối tượng
B.
 reinterpret_cast<kieu_du_lieu> (bieu_thuc): Toán tử reinterpret_cast trong C++ thay đổi một con
trỏ tới bất kỳ kiểu con trỏ khác. Nó cũng cho phép ép kiểu từ con trỏ tới một kiểu integer và ngược
lại.
 static_cast<kieu_du_lieu> (bieu_thuc): Toán tử static_cast trong C++ thực hiện một cast không có
tính đa hình. Ví dụ, nó có thể được sử dụng để ép kiểu một con trỏ lớp cơ sở thành một con trỏ lớp kế
thừa.
Tất cả toán tử ép kiểu trên sẽ được sử dụng trong khi làm việc với lớp và đối tượng. Bây giờ, bạn
thử ví dụ sau để hiểu toán tử ép kiểu đơn giản trong C++. Copy và paste chương trình C++ sau trong
tệp test.cpp, sau đó biên dịch và chạy chương trình:

#include <iostream>
using namespace std;

main()

double a = 15.65653;

float b = 9.02;

int c ;

c = (int) a;

cout << "Dong 1: Gia tri cua (int)a la: " << c << endl ;

c = (int) b;

cout << "Dong 1: Gia tri cua (int)b la: " << c << endl ;

return 0;

Chạy chương trình C++ trên sẽ cho kết quả như hình sau:

You might also like