震旦ad208扫描设置C367如何将扫描的PDF分成多页

2011年9月 C/C++大版内专家分月排行榜第二2011年4月 C/C++大版内专家分月排行榜第二2010年11月 C/C++大版内专家分月排行榜第二
2011年6月 C/C++大版内专家分月排行榜第三
2012年4月 C/C++大版内专家分月排行榜第一
2007年6月 总版技术专家分月排行榜第三
2007年6月 VC/MFC大版内专家分月排行榜第一
2012年4月 C/C++大版内专家分月排行榜第一
本帖子已过去太久远了,不再提供回复功能。C++static_cast类型转换函数
关于强制类型转换的问题,很多书都讨论过,写的最详细的是C++ 之父的《C++
的设计和演化》。最好的解决方法就是不要使用C风格的强制类型转换,而是使用标准C++的类型转换符:static_cast,
dynamic_cast。标准C++中有四个类型转换符:static_cast、dynamic_cast、reinterpret_cast、和const_cast。下面对它们一一进行介绍。
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。强制类型转换&static_cast/dynamic_cast
/articles/336091.html
Q:什么是C风格转换?什么是static_cast, dynamic_cast 以及
reinterpret_cast?区别是什么?为什么要注意?
A:转换的含义是通过改变一个变量的类型为别的类型从而改变该变量的表示方式。为了类型转换一个简单对象为另一个对象你会使用传统的类型转换操作符。比如,为了转换一个类型为doubole的浮点数的指针到整型:
i = int (d);
对于具有标准定义转换的简单类型而言工作的很好。然而,这样的转换符也能不分皂白的应用于类(class)和类的指针。ANSI-C++标准定义了四个新的转换符:'reinterpret_cast',
'static_cast', 'dynamic_cast' 和
'const_cast',目的在于控制类(class)之间的类型转换。
reinterpret_cast(expression)
dynamic_cast(expression)
static_cast(expression)
const_cast(expression)
1 reinterpret_cast
'reinterpret_cast'转换一个指针为其它类型的指针。它也允许从一个指针转换为整数类型。反之亦然。(译注:是指针具体的地址值作为整数值?)
这个操作符能够在非相关的类型之间转换。操作结果只是简单的从一个指针到别的指针的值的二进制拷贝。在类型之间指向的内容不做任何类型的检查和转换。
如果情况是从一个指针到整型的拷贝,内容的解释是系统相关的,所以任何的实现都不是方便的。一个转换到足够大的整型能够包含它的指针是能够转换回有效的指针的。
class A {};
class B {};
A * a = new A;
B * b = reinterpret_cast(a);
'reinterpret_cast'就像传统的类型转换一样对待所有指针的类型转换。
2 static_cast
'static_cast'允许执行任意的隐式转换和相反转换动作。(即使它是不允许隐式的)
应用到类的指针上,意思是说它允许子类类型的指针转换为父类类型的指针(这是一个有效的隐式转换),同时,也能够执行相反动作:转换父类为它的子类。
在这最后例子里,被转换的父类没有被检查是否与目的类型相一致。
class Base {};
class Derived : public Base {};
Base *a = new B
Derived *b = static_cast(a);
'static_cast'除了操作类型指针,也能用于执行类型定义的显式的转换,以及基础类型之间的标准转换:
double d = 3.;
int i = static_cast(d);
3 dynamic_cast
'dynamic_cast'只用于对象的指针和引用。当用于多态类型时,它允许任意的隐式类型转换以及相反过程。不过,与static_cast不同,在后一种情况里(注:即隐式转换的相反过程),dynamic_cast会检查操作是否有效。也就是说,它会检查转换是否会返回一个被请求的有效的完整对象。
检测在运行时进行。如果被转换的指针不是一个被请求的有效完整的对象指针,返回值为NULL.
class Base { virtual dummy() {} };
class Derived : public Base {};
Base* b1 = new D
Base* b2 = new B
Derived* d1 = dynamic_cast(b1); // succeeds
Derived* d2 = dynamic_cast(b2); // fails: returns 'NULL'
如果一个引用类型执行了类型转换并且这个转换是不可能的,一个bad_cast的异常类型被抛出:
class Base { virtual dummy() {} };
class Derived : public Base { };
Base* b1 = new D
Base* b2 = new B
Derived d1 = dynamic_cast(b1); // succeeds
Derived d2 = dynamic_cast(b2); // fails: exception thrown
4 const_cast
这个转换类型操纵传递对象的const属性,或者是设置或者是移除:
class C {};
const C *a = new C;
C *b = const_cast(a);
其它三种操作符是不能修改一个对象的常量性的。
注意:'const_cast'也能改变一个类型的volatile qualifier。
--------------------------------------------------------------------
C++的4种类型转换
一、C 风格(C-style)强制转型如下:
(T) expression // cast expression to be of type T
函数风格(Function-style)强制转型使用这样的语法:
T(expression) // cast expression to be of type T
这两种形式之间没有本质上的不同,它纯粹就是一个把括号放在哪的问题。我把这两种形式称为旧风格(old-style)的强制转型。
二、 C++的四种强制转型形式:
  C++ 同时提供了四种新的强制转型形式(通常称为新风格的或 C++ 风格的强制转型):
  const_cast(expression)
  dynamic_cast(expression)
  reinterpret_cast(expression)
  static_cast(expression)
  每一种适用于特定的目的:
  ·dynamic_cast 主要用于执行“安全的向下转型(safe
downcasting)”,也就是说,要确定一个对象是否是一个继承体系中的一个特定类型。它是唯一不能用旧风格语法执行的强制转型,也是唯一可能有重大运行时代价的强制转型。
·static_cast 可以被用于强制隐型转换(例如,non-const 对象转型为 const 对象,int 转型为
double,等等),它还可以用于很多这样的转换的反向转换(例如,void*
指针转型为有类型指针,基类指针转型为派生类指针),但是它不能将一个 const 对象转型为 non-const 对象(只有
const_cast 能做到),它最接近于C-style的转换。
  ·const_cast 一般用于强制消除对象的常量性。它是唯一能做到这一点的 C++ 风格的强制转型。
  ·reinterpret_cast
是特意用于底层的强制转型,导致实现依赖(implementation-dependent)(就是说,不可移植)的结果,例如,将一个指针转型为一个整数。这样的强制转型在底层代码以外应该极为罕见。
  旧风格的强制转型依然合法,但是新的形式更可取。首先,在代码中它们更容易识别(无论是人还是像 grep
这样的工具都是如此),这样就简化了在代码中寻找类型系统被破坏的地方的过程。第二,更精确地指定每一个强制转型的目的,使得编译器诊断使用错误成为可能。例如,如果你试图使用一个
const_cast 以外的新风格强制转型来消除常量性,你的代码将无法编译。
== dynamic_cast .vs. static_cast
class B { ... };
class D : public B { ... };
void f(B* pb)
D* pd1 = dynamic_cast(pb);
D* pd2 = static_cast(pb);
If pb really points to an object of type D, then pd1 and pd2 will
get the same value. They will also get the same value if pb ==
If pb points to an object of type B and not to the complete D
class, then dynamic_cast will know enough to return zero. However,
static_cast relies on the programmer’s assertion that pb points to
an object of type D and simply returns a pointer to that supposed D
即dynamic_cast可用于继承体系中的向下转型,即将基类指针转换为派生类指针,比static_cast更严格更安全。dynamic_cast在执行效率上比static_cast要差一些,但static_cast在更宽上范围内可以完成映射,这种不加限制的映射伴随着不安全性.static_cast覆盖的变换类型除类层次的静态导航以外,还包括无映射变换,窄化变换(这种变换会导致对象切片,丢失信息),用VOID*的强制变换,隐式类型变换等...
== static_cast .vs. reinterpret_cast
reinterpret_cast是为了映射到一个完全不同类型的意思,这个关键词在我们需要把类型映射回原有类型时用到它.我们映射到的类型仅仅是为了故弄玄虚和其他目的,这是所有映射中最危险的.(这句话是C++编程思想中的原话)
static_cast 和 reinterpret_cast 操作符修改了操作数类型. 它们不是互逆的; static_cast
在编译时使用类型信息执行转换, 在转换执行必要的检测(诸如指针越界计算, 类型检查). 其操作数相对是安全的. 另一方面,
reinterpret_cast 仅仅是重新解释了给出的对象的比特模型而没有进行二进制转换, 例子如下:
int n=9; double d=static_cast & double & (n);
上面的例子中, 我们将一个变量从 int 转换到 double. 这些类型的二进制表达式是不同的. 要将整数 9 转换到 双精度整数
9, static_cast 需要正确地为双精度整数 d 补足比特位. 其结果为 9.0. 而reinterpret_cast
的行为却不同:
double d=reinterpret_cast (n);
这次, 结果有所不同. 在进行计算以后, d 包含无用值. 这是因为 reinterpret_cast 仅仅是复制 n 的比特位到
d, 没有进行必要的分析.&
这些转换的局限性:
static_cast:
在功能上基本上与C风格的类型转换一样强大,含义也一样。它也有功能上限制。例如,你不能用static_cast象用C风格的类型转换一样把struct转换成int类型或者把double类型转换成指针类型,另外,static_cast不能从表达式中去除const属性,因为另一个新的类型转换操作符const_cast有这样的功能。
const_cast:
用于类型转换掉表达式的const或volatileness属性。通过使用const_cast,你向人们和编译器强调你通过类型转换想做的只是改变一些东西的constness或者
volatileness属性。这个含义被编译器所约束。如果你试图使用const_cast来完成修改constness
或者volatileness属性之外的事情,你的类型转换将被拒绝。
dynamic_cast: 它被用于安全地沿着类的继承关系向下进行类型转换。这就是说,你能用dynamic_cast把指向基类的指针或引用转换成指向其派生类或其兄弟类的指针或引用,而且你能知道转换是否成功。失败的转换将返回空指针(当对指针进行类型转换时)或者抛出异常(当对引用进行类型转换时)。
reinterpret_cast:
使用这个操作符的类型转换,其的转换结果几乎都是执行期定义(implementation-defined)。因此,使用reinterpret_casts的代码很难移植。reinterpret_casts的最普通的用途就是在函数指针类型之间进行转换。
/lys2356/item/1e6d30d826bd0353d73aae4c
static_cast、dynamic_cast、reinterpret_cast和const_cast的区别
关于强制类型转换的问题,很多书都讨论过,写的最详细的是C++ 之父的《C++
的设计和演化》。最好的解决方法就是不要使用C风格的强制类型转换,而是使用标准C++的类型转换符:static_cast,
dynamic_cast。标准C++中有四个类型转换符:static_cast、dynamic_cast、reinterpret_cast、和const_cast。下面对它们一一进行介绍。&
static_cast
用法:static_cast & type-id & ( expression_r_r )
该运算符把expression_r_r转换为type-id类型,但没有运行时类型检查来保证转换的安全性。它主要有如下几种用法:
用于类层次结构中基类和子类之间指针或引用的转换。进行上行转换(把子类的指针或引用转换成基类表示)是安全的;进行下行转换(把基类指针或引用转换成子类表示)时,由于没有动态类型检查,所以是不安全的。
用于基本数据类型之间的转换,如把int转换成char,把int转换成enum。这种转换的安全性也要开发人员来保证。
把空指针转换成目标类型的空指针。
把任何类型的表达式转换成void类型。
注意:static_cast不能转换掉expression_r_r的const、volitale、或者__unaligned属性。
dynamic_cast
用法:dynamic_cast & type-id & ( expression_r_r )
该运算符把expression_r_r转换成type-id类型的对象。Type-id必须是类的指针、类的引用或者void
*;如果type-id是类指针类型,那么expression_r_r也必须是一个指针,如果type-id是一个引用,那么expression_r_r也必须是一个引用。
dynamic_cast主要用于类层次间的上行转换和下行转换,还可以用于类之间的交叉转换。
在类层次间进行上行转换时,dynamic_cast和static_cast的效果是一样的;在进行下行转换时,dynamic_cast具有类型检查的功能,比static_cast更安全。
virtual void foo();
class D:public B{
char *m_szName[100];
void func(B *pb){
D *pd1 = static_cast(pb);
D *pd2 = dynamic_cast(pb);
在上面的代码段中,如果pb指向一个D类型的对象,pd1和pd2是一样的,并且对这两个指针执行D类型的任何操作都是安全的;但是,如果pb指向的是一个
B类型的对象,那么pd1将是一个指向该对象的指针,对它进行D类型的操作将是不安全的(如访问m_szName),而pd2将是一个空指针。另外要注意:B要有虚函数,否则会编译出错;static_cast则没有这个限制。这是由于运行时类型检查需要运行时类型信息,而这个信息存储在类的虚函数表(关于虚函数表的概念,详细可见)中,只有定义了虚函数的类才有虚函数表,没有定义虚函数的类是没有虚函数表的。
另外,dynamic_cast还支持交叉转换(cross cast)。如下代码所示。
virtual void f(){}
class B:public A{
class D:public A{
void foo(){
B *pb = new B;
pb-&m_iNum = 100;
D *pd1 = static_cast(pb); //copile error
D *pd2 = dynamic_cast(pb); //pd2 is NULL
在函数foo中,使用static_cast进行转换是不被允许的,将在编译时出错;而使用
dynamic_cast的转换则是允许的,结果是空指针。
reinpreter_cast
用法:reinpreter_cast (expression_r_r)
type-id必须是一个指针、引用、算术类型、函数指针或者成员指针。它可以把一个指针转换成一个整数,也可以把一个整数转换成一个指针(先把一个指针转换成一个整数,在把该整数转换成原类型的指针,还可以得到原先的指针值)。
该运算符的用法比较多。
const_cast
用法:const_cast (expression_r_r)
该运算符用来修改类型的const或volatile属性。除了const 或volatile修饰之外,
type_id和expression_r_r的类型是一样的。
常量指针被转化成非常量指针,并且仍然指向原来的对象;常量引用被转换成非常量引用,并且仍然指向原来的对象;常量对象被转换成非常量对象。
Voiatile和const类试。举如下一例:
void foo(){
const B b1;
b1.m_iNum = 100; //comile error
B b2 = const_cast(b1);
b2. m_iNum = 200; //fine
上面的代码编译时会报错,因为b1是一个常量对象,不能对它进行改变;使用const_cast把它转换成一个常量对象,就可以对它的数据成员任意改变。注意:b1和b2是两个不同的对象。
最容易理解的解释:
dynamic_cast:&&
通常在基类和派生类之间转换时使用;
const_cast:&&
主要针对const和volatile的转换.&&&
static_cast:&&
一般的转换,如果你不知道该用哪个,就用这个。&&&
reinterpret_cast:&&
用于进行没有任何关联之间的转换,比如一个字符指针转换为一个整形数。
已投稿到:8392人阅读
& & & & & static对象如果出现在类中,那么该对象即使从未被使用到,它也会被构造以及析构。而函数中的static对象,如果该函数从未被调用,这个对象也就绝不会诞生,但是在函数每次被调用时检查对象是否需要诞生。
下面详细说说static的功能以及它的来龙去脉:
另外,记住c++的一个哲学基础:你不应该为你并不使用的东西付出任何代价。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:875198次
积分:8163
积分:8163
排名:第2095名
原创:123篇
转载:35篇
评论:67条
(2)(2)(5)(8)(1)(1)(1)(1)(1)(1)(1)(4)(2)(5)(3)(12)(6)(8)(24)(26)(17)(33)}

我要回帖

更多关于 震旦ad248扫描驱动 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信