• 【转】C++标准转换运算符static_cast


    static_cast<new_type> (expression)

    虽然const_cast是用来去除变量的const限定,但是static_cast却不是用来去除变量的static引用。其实这是很容易理解的,static决定的是一个变量的作用域和生命周期,比如:在一个文件中将变量定义为static,则说明这个变量只能在本Package中使用;在方法中定义一个static变量,该变量在程序开始存在直到程序结束;类中定义一个static成员,该成员随类的第一个对象出现时出现,并且可以被该类的所有对象所使用。

    对static限定的改变必然会造成范围性的影响,而const限定的只是变量或对象自身。但无论是哪一个限定,它们都是在变量一出生(完成编译的时候)就决定了变量的特性,所以实际上都是不容许改变的。这点在const_cast那部分就已经体现出来。

    static_cast和reinterpret_cast一样,在面对const的时候都无能为力:两者都不能去除const限定。两者也存在很多的不同,比如static_cast不仅可以用在指针和引用上,还可以用在基础数据和对象上;reinterpret_cast可以用在"没有关系"的类型之间,而用static_cast来处理的转换就需要两者具有"一定的关系"了。

    常用场合

    1、编译器隐式执行的任何类型转换都可以由static_cast来完成,比如int与float、double与char、enum与int之间的转换等。

    double a = 1.999;
    int b = static_cast<int>(a); //相当于b = a ;

    当编译器隐式执行类型转换时,大多数的编译器都会给出一个警告:

    e:vs 2010 projectsstatic_caststatic_caststatic_cast.cpp(11): warning C4244: “初始化”: 从“double”转换到“int”,可能丢失数据

    使用static_cast可以明确告诉编译器,这种损失精度的转换是在知情的情况下进行的,也可以让阅读程序的其它程序员明确你是有意识的转换而不是由于疏忽。

    把精度大的类型转换为精度小的类型,static使用位截断进行处理。

    2、使用static_cast可以找回存放在void*指针中的值。

    double a = 1.999;
    void * vptr = & a;
    double * dptr = static_cast<double*>(vptr);
    cout<<*dptr<<endl;//输出1.999

    3、static_cast也可以用在基类与派生类指针或引用类型之间的转换。然而它不做运行时的检查,不如dynamic_cast安全。static_cast仅仅是依靠类型转换语句中提供的信息来进行转换,而dynamic_cast则会遍历整个类继承体系进行类型检查,因此dynamic_cast在执行效率上会比static_cast要差一些。

    现在我们有父类与其派生类如下:

    class ANIMAL
    {
    public:
        ANIMAL():_type("ANIMAL"){};
        virtual void OutPutname(){cout<<"ANIMAL";};
    private:
        string _type ;
    };
    class DOG:public ANIMAL
    {
    public:
        DOG():_name("大黄"),_type("DOG"){};
        void OutPutname(){cout<<_name;};
        void OutPuttype(){cout<<_type;};
    private:
        string _name ;
        string _type ;
    };

    此时我们进行派生类与基类类型指针的转换:注意从下向上(子类到基类)的转换是安全的,从上向下(基类到子类)的转换不一定安全。

    int main()
    {
        //基类指针转为派生类指针,且该基类指针指向基类对象。
        ANIMAL * ani1 = new ANIMAL ;
        DOG * dog1 = static_cast<DOG*>(ani1);
        //dog1->OutPuttype();//错误,在ANIMAL类型指针不能调用方法OutPutType();在运行时出现错误。
    
        //基类指针转为派生类指针,且该基类指针指向派生类对象
        ANIMAL * ani3 = new DOG;
        DOG* dog3 = static_cast<DOG*>(ani3);
        dog3->OutPutname(); //正确//
        system("pause");
    
    }

    从上边对static_cast分析可以看出,static_cast跟传统转换方式几乎是一致的,所以只要将static_cast和圆括号去掉,再将尖括号改成圆括号就变成了传统的显式转换方式。

    转自:

    http://www.cnblogs.com/ider/archive/2011/07/31/cpp_cast_operator_part4.html

    http://www.cnblogs.com/QG-whz/p/4509710.html

  • 相关阅读:
    celery beat之pidfile already exists问题
    HBase源码系列之HFile
    吴裕雄--天生自然 JAVA开发学习:集合框架
    吴裕雄--天生自然 诗经:小池
    吴裕雄--天生自然 诗经:所见
    吴裕雄--天生自然 JAVA开发学习:数据结构
    吴裕雄--天生自然 JAVA开发学习:包(package)
    吴裕雄--天生自然 JAVA开发学习:接口
    吴裕雄--天生自然 JAVA开发学习:封装
    吴裕雄--天生自然 JAVA开发学习:抽象类
  • 原文地址:https://www.cnblogs.com/codingmengmeng/p/7650506.html
Copyright © 2020-2023  润新知