2009-09-03 28 views

Trả lời

12

Nói chung, đúc dùng để chỉ một chuyển đổi rõ ràng, cho dù nó được thực hiện bởi C-style cast (T(v) hoặc (T)v) hoặc C++ - phong cách cast (static_cast, const_cast, dynamic_cast, hoặc reinterpret_cast). Chuyển đổi nói chung là một thuật ngữ chung chung hơn được sử dụng cho bất kỳ lúc nào một biến được chuyển đổi sang một biến khác:

std::string s = "foo"; // Conversion from char[] to char* to std::string 
int i = 4.3; // Conversion from float to int 
float *f = reinterpret_cast<float*>(&i); // (illegal) conversion from int* to float* 
+0

do đó không có sự khác biệt nào –

+0

Sự khác biệt là dàn diễn viên * rõ ràng *. Các từ khóa C++ có thể được grep'ed. Cả diễn viên C và C++ đều cho thấy việc chuyển đổi đã được thực hiện đúng mục đích và với sự đồng ý của lập trình viên.Một chuyển đổi tiềm ẩn có thể được dự định, hoặc do nhầm lẫn. – DevSolar

0

Một trong những khác biệt lớn xảy ra khi bạn làm việc với chuỗi. Bạn không thể nói (int) "234" và nhận được số nguyên 234. Loại đúc thường chỉ hoạt động trên các kiểu dữ liệu số nguyên thủy.

2

Loại đúc nghĩa là bạn lấy một chuỗi bit và diễn giải chúng khác nhau. Loại chuyển đổi có nghĩa là bạn chuyển đổi một chuỗi các bit từ một cấu hình hữu ích trong một ngữ cảnh thành một cấu hình hữu ích trong một ngữ cảnh khác.

Ví dụ, giả sử tôi viết

int x=65; 
char c=(char) x; 
char* s=(char*) x; 

c bây giờ sẽ chứa ký tự 'A', bởi vì nếu tôi diễn giải các số thập phân 65 như một nhân vật, tôi nhận được lá thư 'A'. s bây giờ sẽ là một con trỏ đến một chuỗi ký tự cư trú tại vị trí bộ nhớ 65. Điều này gần như chắc chắn là một điều vô dụng để làm, như tôi không có ý tưởng những gì đang ở vị trí bộ nhớ đó.

itoa(x, s, 10); 

là một loại chuyển đổi. Điều đó sẽ cho tôi chuỗi "65".

Tức là, với phôi, chúng tôi vẫn đang xem cùng một vị trí bộ nhớ. Chúng tôi chỉ giải thích dữ liệu ở đó một cách khác nhau. Với các chuyển đổi, chúng tôi đang tạo ra dữ liệu mới có nguồn gốc từ dữ liệu cũ, nhưng nó không giống với dữ liệu cũ.

+0

Vì vậy, bạn đang nói, 'reinterpret_cast' thực hiện truyền, nhưng' static_cast' (mặc dù tên của nó) thực hiện chuyển đổi? Tôi sẽ thấy rằng khó hiểu nhất. – jogojapan

1

Loại đúc có thể làm một số tiền tối thiểu của chuyển đổi:

signed char Schar; // 1 byte (8 bits) to hold 256 values: -128 to 127 
unsigned char Uchar; // 1 byte (8 bits) to hold 256 values: 0 to 255 
... 
if (Schar < -10 ) ... // compiler uses SIGNED comparision 
Uchar = Schar; // implicit conversion only copies the 8 bits 
Uchar = (char) Schar; // explicit conversion may be required by compiler 
if (Uchar > 200) ... // compiler uses UNSIGNED comparision 
...OR... 
if ((unsigned char) Schar > 200) ... // explicit conversion for UNSIGNED comparision 

short Sshort; // 2 bytes (16 bits) to hold 65536 values: -32768 to 32767 
unsigned short Ushort; // 2 bytes (16 bits) to hold 65536 values: 0 to 65536 
... 
// when moving 8 bits into 16 bit variables, what to do with other 8 bits ? 
Sshort = (signed short) Uchar; // move 8 bits over and use 0s for other 8 bits 
Sshort = (signed short) Schar; // same, but use 1s if negative to make Sshort negative 

Nhưng điều này có thể được coi Loại chuyển đổi:

float dbl; // 4 bytes to store floating number in IEEE format 
long lng; // 4 bytes to store 32 bit integer value in 2's complement format 
... 
dbl = lng; // convert from 2's comp to IEEE format - all bits change ! 
dbl = (float) lng; // explicit form 

LƯU Ý: int thường là giống như short hoặc long tùy thuộc vào trình biên dịch/CPU LƯU Ý: signed thường là tùy chọn vì đây thường là mặc định

Không chuyển đổi diễn ra khi bạn chỉ định tất cả các biến chiếm không gian bộ nhớ giống nhau:

typedef union MYUNION // all members occupy same space (memory bytes) 
{ 
    signed char Schar; // usual default for char 
    unsigned char Uchar; 
    signed short Sshort; // usual default for short 
    unsigned short Ushort; 
    signed long Slong; // usual default for long 
    unsigned long Ulong; 
    float flt; 
    double dbl; 
}; 

MYUNION myunion; 

myunion.Schar = ... // set variable (memory byte) to value 

if ((unsigned char) myunion.Schar > 200) ... // unsigned compare works ok 
... is same as (also without moving any data around) ... 
if (myunion.Uchar > 200) ... // unsigned compare works ok 

... myunion.Sshort ... // other 8 bits are UNASSIGNED GARBAGE ! 

myunion.Sshort = myunion.Schar; // provide all 16 bits from Schar 
... myunion.Sshort ... // Sshort of valid now 

myunion.dbl = 12345.0; 
... myunion.Ulong ... // has weird value from odd IEEE bit format 

myunion.Ulong = (unsigned long) myunion.dbl; // do explicit conversion 
... myunion.Ulong ... // has CONVERTED 12345 value 

LƯU Ý: *(unsigned long*)&dbl cũng sản xuất giá trị kỳ lạ. Nó có: a) lấy địa chỉ (vị trí của bit và byte) của double dbl b) xem xét địa chỉ như một địa chỉ của một unsigned dài c) được unsigned dài từ vị trí đó Tất nhiên, có một số ứng dụng thực tế của kỹ thuật này. Ví dụ: phân tích cú pháp tệp nhị phân bên ngoài phức tạp hoặc trên CPU có 512 byte bộ nhớ, v.v.

Các vấn đề liên quan