青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

S.l.e!ep.¢%

像打了激速一樣,以四倍的速度運轉,開心的工作
簡單、開放、平等的公司文化;尊重個性、自由與個人價值;
posts - 1098, comments - 335, trackbacks - 0, articles - 1
  C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

C++:Type Casting

Posted on 2010-10-08 14:08 S.l.e!ep.¢% 閱讀(810) 評論(0)  編輯 收藏 引用 所屬分類: C++
Converting an expression of a given type into another type is known as ? type-casting . We have already seen some ways to type cast:

Implicit conversion

Implicit conversions do not require any operator. They are automatically performed when a value is copied to a compatible type. For example:

														
																short
														 a=2000;
int b;
b=a;

Here, the value of?a?has been promoted from?short?to?int?and we have not had to specify any type-casting operator. This is known as a standard conversion. Standard conversions affect fundamental data types, and allow conversions such as the conversions between numerical types (short?to?int,?int?to?float,?double?to?int...), to or from?bool, and some pointer conversions. Some of these conversions may imply a loss of precision, which the compiler can signal with a warning. This can be avoided with an explicit conversion.

Implicit conversions also include constructor or operator conversions, which affect classes that include specific constructors or operator functions to perform conversions. For example:

														
																class
														 A {};
class B { public: B (A a) {} };

A a;
B b=a;

Here, a implicit conversion happened between objects of?class A?and?class B, because?B?has a constructor that takes an object of class?A?as parameter. Therefore implicit conversions from?A?to?B?are allowed.

Explicit conversion

C++ is a strong-typed language. Many conversions, specially those that imply a different interpretation of the value, require an explicit conversion. We have already seen two notations for explicit type conversion: functional and c-like casting:

														
																short
														 a=2000;
int b;
b = (int) a;    // c-like cast notation
b = int (a);    // functional notation

The functionality of these explicit conversion operators is enough for most needs with fundamental data types. However, these operators can be applied indiscriminately on classes and pointers to classes, which can lead to code that while being syntactically correct can cause runtime errors. For example, the following code is syntactically correct:

														
																// class type-casting
														
														
																#include <iostream>
														
														
																using
														
														
																namespace
														 std;

class CDummy {
    float i,j;
};

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;
}
												

The program declares a pointer to?CAddition, but then it assigns to it a reference to an object of another incompatible type using explicit type-casting:

padd = (CAddition*) &d;

Traditional explicit type-casting allows to convert any pointer into any other pointer type, independently of the types they point to. The subsequent call to member?result?will produce either a run-time error or a unexpected result.

In order to control these types of conversions between classes, we have four specific casting operators:?dynamic_cast,?reinterpret_cast,?static_cast?and?const_cast. Their format is to follow the new type enclosed between angle-brackets (<>) and immediately after, the expression to be converted between parentheses.

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

The traditional type-casting equivalents to these expressions would be:

(new_type) expression
new_type (expression)

but each one with its own special characteristics:

dynamic_cast: 轉換子類的指針(或引用)為父類的指針(或引用)

dynamic_cast?can be used only with pointers and references to objects. Its purpose is to ensure that the result of the type conversion is a valid complete object of the requested class.

Therefore,?dynamic_cast?is always successful when we cast a class to one of its base classes:

														
																class
														 CBase { };
class CDerived: public CBase { };

CBase b; CBase* pb;
CDerived d; CDerived* pd;

pb = dynamic_cast<CBase*>(&d);     // ok: derived-to-base
pd = dynamic_cast<CDerived*>(&b);  // wrong: base-to-derived

The second conversion in this piece of code would produce a compilation error since base-to-derived conversions are not allowed with?dynamic_cast?unless the base class is polymorphic.

When a class is polymorphic,?dynamic_cast?performs a special checking during runtime to ensure that the expression yields a valid complete object of the requested class:

														
																// dynamic_cast
														
														
																#include <iostream>
														
														
																#include <exception>
														
														
																using
														
														
																namespace
														 std;

class CBase { virtualvoid dummy() {} };
class CDerived: public CBase { int a; };

int main () {
  try {
    CBase * pba = new CDerived;
    CBase * pbb = new CBase;
    CDerived * pd;

    pd = dynamic_cast<CDerived*>(pba);
    if (pd==0) cout << "Null pointer on first type-cast" << endl;

    pd = dynamic_cast<CDerived*>(pbb);
    if (pd==0) cout << "Null pointer on second type-cast" << endl;

  } catch (exception& e) {cout << "Exception: " << e.what();}
  return 0;
}
Null pointer on second type-cast

Compatibility note:?dynamic_cast?requires the Run-Time Type Information (RTTI) to keep track of dynamic types. Some compilers support this feature as an option which is disabled by default. This must be enabled for runtime type checking using?dynamic_cast?to work properly.

The code tries to perform two dynamic casts from pointer objects of type?CBase*?(pba?and?pbb) to a pointer object of type?CDerived*, but only the first one is successful. Notice their respective initializations:

CBase * pba = new CDerived;
CBase * pbb = new CBase;

Even though both are pointers of type?CBase*,?pba?points to an object of type?CDerived, while?pbb?points to an object of type?CBase. Thus, when their respective type-castings are performed using?dynamic_cast,?pba?is pointing to a full object of class?CDerived, whereas?pbb?is pointing to an object of class?CBase, which is an incomplete object of class?CDerived.

When?dynamic_cast?cannot cast a pointer because it is not a complete object of the required class -as in the second conversion in the previous example- it returns a null pointer to indicate the failure. If?dynamic_cast?is used to convert to a reference type and the conversion is not possible, an exception of type?bad_cast?is thrown instead.

dynamic_cast?can also cast null pointers even between pointers to unrelated classes, and can also cast pointers of any type to void pointers (void*).

static_cast: 指針的轉換: 1. 子類和父類之間指針互相轉換(不進行安全檢查). 非指針的轉換: 2. 標準隱式轉換(如int->float, double->int). 3. 用戶定義轉換(構造函數轉換,轉換函數)

static_cast ? can perform conversions between pointers to related classes, not only from the derived class to its base, but also from a base class to its derived. This ensures that at least the classes are compatible if the proper object is converted, but no safety check is performed during runtime to check if the object being converted is in fact a full object of the destination type. Therefore, it is up to the programmer to ensure that the conversion is safe. On the other side, the overhead of the type-safety checks of ? dynamic_cast ? is avoided.

														
																class
														 CBase {};
class CDerived: public CBase {};
CBase * a = new CBase;
CDerived * b = static_cast<CDerived*>(a);

This would be valid, although?b?would point to an incomplete object of the class and could lead to runtime errors if dereferenced.

static_cast?can also be used to perform any other non-pointer conversion that could also be performed implicitly, like for example standard conversion between fundamental types:

														
																double
														 d=3.14159265;
int i = static_cast<int>(d); 

Or any conversion between classes with explicit constructors or operator functions as described in "implicit conversions" above.

reinterpret_cast: 1. 任何指針之間的相互轉換,即使這些類型之間沒有任何關系. 2. 指針和整數類型的相互轉換(指針->int時在Mac上會報錯: loses precision).

reinterpret_cast ? converts any pointer type to any other pointer type, even of unrelated classes. The operation result is a simple binary copy of the value from one pointer to the other. All pointer conversions are allowed: neither the content pointed nor the pointer type itself is checked.

It can also cast pointers to or from integer types. The format in which this integer value represents a pointer is platform-specific. The only guarantee is that a pointer cast to an integer type large enough to fully contain it, is granted to be able to be cast back to a valid pointer.

The conversions that can be performed by?reinterpret_cast?but not by?static_cast?have no specific uses in C++ are low-level operations, whose interpretation results in code which is generally system-specific, and thus non-portable. For example:

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

This is valid C++ code, although it does not make much sense, since now we have a pointer that points to an object of an incompatible class, and thus dereferencing it is unsafe.

const_cast: 轉換對象(primitive類型的不可以: int, float, double...),指針,引用的const屬性,有則去掉,沒有則加上

This type of casting manipulates the constness of an object, either to be set or to be removed. For example, in order to pass a const argument to a function that expects a non-constant parameter:

														
																// const_cast
														
														
																#include <iostream>
														
														
																using
														
														
																namespace
														 std;

void print (char * str)
{
  cout << str << endl;
}

int main () {
  constchar * c = "sample text";
  print ( const_cast<char *> (c) );
  return 0;
}
sample text

typeid

typeid ? allows to check the type of an expression:

typeid (expression)

This operator returns a reference 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 one using operators?==?and?!=?or can serve to obtain a null-terminated character sequence representing the data type or class name by using its?name()?member.

														
																// typeid
														
														
																#include <iostream>
														
														
																#include <typeinfo>
														
														
																using
														
														
																namespace
														 std;

int main () {
  int * a,b;
  a=0; b=0;
  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: int *
b is: int  

When?typeid?is applied to classes?typeid?uses the RTTI to keep track of the type of dynamic objects. When typeid is applied to an expression whose type is a polymorphic class, the result is the type of the most derived complete object:

														
																// typeid, polymorphic class
														
														
																#include <iostream>
														
														
																#include <typeinfo>
														
														
																#include <exception>
														
														
																using
														
														
																namespace
														 std;

class CBase { virtualvoid f(){} };
class CDerived : public CBase {};

int main () {
  try {
    CBase* a = new CBase;
    CBase* b = new CDerived;
    cout << "a is: " << typeid(a).name() << '\n';
    cout << "b is: " << typeid(b).name() << '\n';
    cout << "*a is: " << typeid(*a).name() << '\n';
    cout << "*b is: " << typeid(*b).name() << '\n';
  } catch (exception& e) { cout << "Exception: " << e.what() << endl; }
  return 0;
}
a is: class CBase *
b is: class CBase *
*a is: class CBase
*b is: class CDerived

Notice how the type that?typeid?considers for pointers is the pointer type itself (both?a?and?b?are of type?class CBase *). However, when?typeid?is applied to objects (like?*a?and?*b)?typeid?yields their dynamic type (i.e. the type of their most derived complete object: 真實的類型,即使子類對象使用的是父類的指針,但返回的子類的信息).

If the type?typeid?evaluates is a pointer preceded by the dereference operator (*), and this pointer has a null value,?typeid?throws a?bad_typeid?exception.

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲精品欧美激情| 另类人畜视频在线| 女人色偷偷aa久久天堂| 亚洲自拍偷拍视频| 亚洲一区在线视频| 正在播放欧美一区| 亚洲综合第一| 欧美日韩高清区| 欧美午夜在线观看| 国产日韩精品一区观看| 雨宫琴音一区二区在线| 亚洲精品欧美在线| 亚洲午夜一区| 老色鬼久久亚洲一区二区| 欧美国产第一页| 日韩一级精品视频在线观看| 亚洲欧美视频在线| 美女视频黄a大片欧美| 欧美三级在线| 在线成人免费观看| 亚洲自拍电影| 欧美高清在线一区二区| 在线视频日韩精品| 久久一本综合频道| 国产精品xxx在线观看www| 国产一区二区按摩在线观看| 亚洲精品在线观看视频| 欧美中文在线观看国产| 亚洲黑丝在线| 翔田千里一区二区| 蜜臀99久久精品久久久久久软件| 国产精品激情偷乱一区二区∴| 国产一区二区三区的电影 | 亚洲欧美在线免费观看| 六月天综合网| 国产日韩精品在线| 亚洲天堂成人在线视频| 欧美国产日本高清在线| 午夜久久tv| 欧美日韩在线亚洲一区蜜芽| 狠狠色丁香婷综合久久| 亚洲欧美影院| 亚洲美女电影在线| 欧美成人一区二区在线| 狠狠色噜噜狠狠色综合久| 亚洲一区三区电影在线观看| 亚洲电影网站| 麻豆国产va免费精品高清在线| 一本色道久久88精品综合| 久久久久这里只有精品| 亚洲主播在线| 欧美午夜久久| 一区二区不卡在线视频 午夜欧美不卡在 | 亚洲第一网站| 久色婷婷小香蕉久久| 国产日韩一区二区三区在线播放| 亚洲午夜精品一区二区三区他趣| 亚洲大胆女人| 另类国产ts人妖高潮视频| 在线观看国产精品网站| 久久天天躁狠狠躁夜夜av| 欧美一区二区高清| 国模 一区 二区 三区| 久久精品1区| 久久大综合网| 伊人久久大香线| 欧美成人一区二区三区| 噜噜噜噜噜久久久久久91| 亚洲电影天堂av| 欧美xart系列高清| 欧美成人自拍| avtt综合网| 一本一本大道香蕉久在线精品| 欧美色中文字幕| 午夜日韩av| 久久久av毛片精品| 亚洲日本视频| 一本大道久久a久久精二百| 国产精品久久久久久亚洲毛片| 性高湖久久久久久久久| 欧美一区成人| 日韩视频精品| 亚洲在线电影| 樱桃国产成人精品视频| 亚洲欧洲另类| 国产精品视频1区| 久久精品视频va| 欧美不卡激情三级在线观看| 亚洲一区二区三区777| 一本一本大道香蕉久在线精品| 日韩午夜视频在线观看| 国产日韩欧美一区二区| 亚洲国产高清aⅴ视频| 国产精品久久久久久久久搜平片 | 亚洲电影观看| 亚洲午夜精品国产| 樱桃国产成人精品视频| 99这里有精品| 国产尤物精品| 亚洲乱码国产乱码精品精天堂 | 亚洲精品影视| 国产在线拍偷自揄拍精品| 亚洲福利视频二区| 国产日产欧产精品推荐色 | 蜜臀久久99精品久久久久久9| 欧美欧美全黄| 久久综合色影院| 欧美午夜精品理论片a级大开眼界| 久久视频精品在线| 欧美日韩亚洲综合在线| 蜜桃久久av一区| 国产精品免费观看视频| 亚洲韩国精品一区| 亚洲二区视频| 久久国产精品久久w女人spa| 亚洲午夜av在线| 欧美成人一区二免费视频软件| 欧美一区二区三区四区在线观看 | 亚洲国产精品久久久| 性色av一区二区三区在线观看| 在线亚洲成人| 免费欧美高清视频| 国产日产欧美a一级在线| 亚洲精品美女久久7777777| 亚洲电影免费观看高清完整版在线观看 | 亚洲乱码日产精品bd| 久久久久五月天| 久久电影一区| 国产视频久久网| 亚洲欧美国产高清va在线播| 亚洲一区二区在线免费观看视频| 欧美电影在线播放| 亚洲高清三级视频| 91久久综合亚洲鲁鲁五月天| 久久夜色精品一区| 欧美aⅴ99久久黑人专区| 国内久久精品视频| 久久精彩免费视频| 久久综合网色—综合色88| 国产一区二区在线免费观看| 午夜精品国产更新| 久久精品观看| 很黄很黄激情成人| 久久久7777| 美女网站在线免费欧美精品| 精品99一区二区三区| 久久久免费精品视频| 久久久国产精品一区二区中文| 韩日欧美一区二区| 麻豆av一区二区三区久久| 亚洲第一二三四五区| aaa亚洲精品一二三区| 国产精品久久久久久久久果冻传媒| 亚洲色图自拍| 国产精品一页| 欧美在线免费| 欧美风情在线观看| 一区二区不卡在线视频 午夜欧美不卡在 | 久久久免费精品| 在线看片一区| 欧美激情精品久久久久久久变态| 激情欧美一区二区三区| 麻豆成人精品| 一区二区成人精品| 久久婷婷综合激情| 亚洲精品午夜精品| 国产精品久久午夜夜伦鲁鲁| 久久成人羞羞网站| 亚洲乱码国产乱码精品精98午夜| 亚洲女女做受ⅹxx高潮| 好吊色欧美一区二区三区视频| 久久精品欧美日韩| 亚洲精品中文字幕在线| 久久国产高清| 亚洲国产精品一区二区www在线| 欧美日本精品一区二区三区| 亚洲嫩草精品久久| 亚洲国产成人在线| 久久激情综合网| 在线性视频日韩欧美| 在线看欧美日韩| 国产日韩欧美三区| 欧美色欧美亚洲高清在线视频| 久久精品青青大伊人av| 99国产麻豆精品| 欧美jizz19性欧美| 欧美一区影院| 亚洲精品久久| 国产亚洲二区| 欧美日韩一区二区三区四区在线观看 | 欧美午夜剧场| 猛男gaygay欧美视频| 性伦欧美刺激片在线观看| 日韩午夜中文字幕| 欧美激情aⅴ一区二区三区| 久久久久久久久伊人| 亚洲免费影视| 亚洲午夜在线观看| 日韩午夜高潮| 亚洲精品视频在线观看免费|