C++类型转换之小结(二)

2014-11-24 09:57:56 · 作者: · 浏览: 4
有两个参数:一个是类型名;另一个是多态对象的指针或引用。其功能是在运行时将对象强制转换为目标类型并返回布尔型结果。也就是说,如果该函数成功地并且是动态的将 *pfile 强制转换为 MediaFile,那么 pfile的动态类型是 MediaFile 或者是它的派生类。否则,pfile 则为其它的类型:

  void menu::build(const File * pfile)

  {

  if (dynamic_cast (pfile))

  {

  // pfile 是 MediaFile 或者是MediaFile的派生类 LocalizedMedia

  add_option("play");

  }

  else if (dynamic_cast (pfile))

  {

  // pfile 是 TextFile 是TextFile的派生类

  add_option("edit");

  }

  }

  细细想一下,虽然使用 dynamic_cast 确实很好地解决了我们的问题,但也需要我们付出代价,那就是与 typeid 相比,dynamic_cast 不是一个常量时间的操作。为了确定是否能完成强制类型转换,dynamic_cast`必须在运行时进行一些转换细节操作。因此在使用 dynamic_cast 操作时,应该权衡对性能的影响。

(2)static_cast

1)完成向上类型转换,即将指向派生类的指针或引用转换为指向同一层次中的一个基类的指针或引用。

2) 使用例子

[cpp]
#include
class B
{
int i;
public: // Conversion constructor.
B(int a) : i(a) { }
void display()
{
std::cout << i;
}
};
int main()
{
B bobj1 = (B)123; // C-style cast int to B.
bobj1.display();
std::cout << '/';
bobj2 = B(456); // Constructor notation B
bobj2.display();
std::cout << '/';
B bobj3 = static_cast(789); // Static_cast.
bobj3.display();
return 0;
}
(3)reinterpret_cast

reinterpret_cast操作符代替了大多数其它C风格类型转换的使用。reinterpret_cast将指针转换为其它指针类型、将数字转换为指针或将指针转换为数字。与使用C风格的类型转换一样,当使用reinterpret_cast操作符时,用户应该知道自已要干什么。有时,只有C风格的类型转换才能起作用,但这并不是说从来都不应该使用reinterpret_cast。下例展示了一个用void型指针返回100个字符的缓冲区的简单内存分配程序。Main()函数将返回结果赋值给一个字符型指针。C++的转换规则与C并不相同。在C++的转换规则中,不能隐式地将void*转换为char*,因此,需要进行类型转换。下面使用了reinterpret_cast而不是C语言风格的类型转换。

[cpp]
#include
#include
//Create a buffer. //
void* getmem()
{
static char buf[100];
return buf;
}
int main()
{
char* cp = reinterpret_cast(getmem());
strcpy(cp, "Hello, Woody");
std::cout << cp;
return 0;
}
(4)const_cast

刚才所讨论的3种类型转换操作都没有涉及“常量属性”,即不能使用它们移去对象的常量属性。为此,我们要使用const_cast操作符。除了const和volatile关键字之外,它的类型参数必须和对象参数的类型相匹配。
例如,考虑一个全局的计数器,它描述了对常类对象或其它类型的类对象的操作次数。下面给出了这样的一个例子

[cpp
#include
class A
{
int val;
int rptct; // Number of times the object is reported.
public:
A(int v) : val(v), rptct(0) { }
~A()
{
cout << val << " was reported " << rptct << " times.";
}
void report() const;
};
void A::report() const
{
const_cast(this)->rptct++;
cout << val << endl;
}
int main()
{
const A a(123);
a.report();
a.report();
a.report();
return 0;
}