zoukankan      html  css  js  c++  java
  • 条款27:尽量少做转型动作

    首先是C++提供的四种转型操作:

    1. const_cast:常量性的转除。
    2. dynamic_cast:安全的向derived class进行转型,可能会带来很高的开销
    3. reinterpret_cast:低级转型,例如可讲pointer转成int,不建议使用
    4. static_cast: 强迫隐式转换,例如int to const int,int to double, 但是const int 到 int 只有const_cast能做到。
    在我们面前经常出现的一种使用情况是,像下面这样:
     1 class Window{
     2 public:
     3     virtual    void onResize(){...}
     4     ...
     5 };
     6 class SpecialWindow: public Window{
     7 public:
     8     virtual void onResize(){
     9         static_cast<Window>(*this),onResize();
    10         ...
    11     }
    12     ...
    13 }
    但是实际上上面的副本不能如愿以偿的调用其基类部分的onResize(),其事实上调用的是SpecialWindow的基类部分的副本的的单独的onResize,实际上和SpecialWindow的resize没有什么关系。这时,如果SpecialWindow本身也尝试去修改SpecialWidnow的非基类部分的话,那么对象就会进入一种伤残的状态.其基类部分没有进行必要的修改,但是派生类单独的部分却经历了修改,这样对象就会进入一种伤残的状态.
    其实调用基类的Resize的正确方法根本就不需要用到转型操作:
    class SpecialWindow:public Window{
    public:
        virtual void onResize(){
            Window::onResize(){
                .......
            }
            ...
        }
    };
    再论dynamic_cast,记住一般起调用带来的开销还是比较大的。而一般需要dynamic_cast的主要情况是,只拥有一个base class 指针的情况下,想要对derived class进行单独的处理。一般有两种方式可以替代dynamic_cast达到这种效果.
    第一种方法是取一个容器并在里面存储,直接指向derived class对象的指针(往往是智能指针)。
    typedef vector<shared_ptr<SpecialWindow>> VPSW;
    VPSW windPtrs;
    ...
    for(VPSW::iterator iter = windPtrs.begin(); 
        iter != windPtrs.end(); ++iter){
        iter->blink();
    }
    还有一种方法就是,将虚函数从derived class向上再延伸一层,这样,直接使用Base class 的指针,就可以调用derived class的函数。
    记住,优秀的代码是很少使用转型操作的,应该尽可能的隔离转型操作。
    小结:
    1. 如果可以应该尽量减少转型的使用,尤其是dynamc_cast(其会消耗很多的资源)。
    2. 如果需要转型,那么至少应该将他隐藏起来,例如放置到某个函数内使用。
    3. 如果使用转型,那么一定要使用新式转型。
  • 相关阅读:
    Scrapy
    关于函数名称和库函数名称冲突的故事
    Hibernate的一级缓存
    spring-mvc 与 openid4java
    openid4java 使用记录[转载]
    Linux定时任务Crontab详解_定时备份
    Spring的线程池ThreadPoolTaskExecutor使用案例
    BZOJ4275 : [ONTAK2015]Badania naukowe
    BZOJ4137 : [FJOI2015]火星商店问题
    BZOJ2832 : 宅男小C
  • 原文地址:https://www.cnblogs.com/-wang-cheng/p/4867321.html
Copyright © 2011-2022 走看看