zoukankan      html  css  js  c++  java
  • C++ 转型动作 尽量避免 以及 那些意想不到的威胁

    看完EffectiveC++的关于转型的章节,顿时认为周围的代码都处在悬崖边上~~




    C的旧式转型inta = 10; double b = (double)a;

    对于C++的四种转型函数,

    const_cast去掉对象的常量性(仅仅此一个操作符有此功能!)

    dynamic_cast一般用于继承体系中某对象的归属,耗费较大

    reinterpret_cast低级转型,差点儿不用。

    static_cast强迫隐式转换int->double, void * ->typed *


    在类的expecilit构造函数中,比如:


    class Widget
    {
    public:
     explicit: Widget(int size);
    ....
    };

    旧式转型有时也用,比方在,对于一个须要Widget对象作为參数的函数中,比如:voidf( Widget &w ); 调用时,使用旧式转型f(Widget(15));


    转型并不不过只告诉编译器将该对象视为什么类型,编译器会做出一些动作来完毕转型,比如:

    int转化为double,在完毕浮点数的乘法的时候,显然是要产生不同的目标码的。




    以下的样例可能你每天都在用,那就是"基类的指针指向子类的对象",比如:

    class Based { ... };

    class Derived: public Based{ ... };

    Derived de;

    Based *pb = &de; //基类的指针指向子类的对象。

    在实际。这两个指针的值可能不一样,也许是在当前对象上加了一个偏移量,这也就意味着,同一个Derived对象可能有两个地址,基类类型的指针与派生类类型的指针可能是不一样的。当然这依赖于内存布局(啊哦,不可移植性~~


    一个接着一个,看似平时非常习惯的东西,却一个一个的有着潜在的威胁:

    class Parent
    {
    public:
        virtual void Func() {...}
        ...;
    };
    class Child : public Parent
    {
    public:
        virtual void Func() 
        {
            static_cast<Parent>(*this).Func();
            ...; //子类自己的操作。
        }
    };

    在子类中调用父类定义的函数。这是再寻常只是的事了。

    但是以下的代码却非常危急:

    上面这段简单的代码,子类的Func函数首先调用父类的,再做子类的操作。但是,这里的static_cast得到的是一个暂时副本,那么也就是说你的Func函数假设试图改动子类的成员,那么父类的部分是再暂时副本上做的,也就是说,你可能会得到一个父类没有改动,子类改动了的病态的对象。太可怕了,不是要尽量使用static_cast。要实现上述功能,直接指定作用域就可以,即使用Parent::Fun()函数来调用。

    PS:尽量少用转型。




    对于dynamic_cast,那就更应当敬而远之了,除了运行速度非常慢,尤事实上在多重继承或是多层继承中,简单的类名搜索成本就非常高了。

    那么我们就必须知道,什么时候我们必须使用dynamic_cast呢?

    如今你仅仅有指向base”的指针或者引用,可是你须要的是对一个derived对象运行derivedclass的操作函数,你仅仅能靠它们来处理对象。这里全然能够避免使用dynamic_cast,方法为:

    1不要忘了虚函数。。详细定义參见:

    2不要忘了智能指针,使用容器存放指向derived类的智能指针,这样变消除了使用base接口来处理对象的必要性,关于智能指针,參见智能指针




    请记得:

    在注重效率的应用中,对转型动作敬而远之吧!

    假设必须转型,那么记得封装在函数里面,不要让这些恼人的代码干扰用户代码。

    使用新式转型,各司其职,不易出错,比較easy在源码中识别出来。

    假设你认为你必须使用转型,请再想想,迈出这危急的一步的代价~~~




  • 相关阅读:
    nyist 287 Redar
    nyist 14 会场安排问题
    nyist 90 整数分割
    nyist 123 士兵杀敌四
    nyist 116 士兵杀敌
    nyist 277 车牌号
    nyist 590 相同的和
    寄宿于WindowsService的WebAPI
    C#Dictionary 字典、泛型
    Repository模式
  • 原文地址:https://www.cnblogs.com/blfshiye/p/3762340.html
Copyright © 2011-2022 走看看