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. 如果使用转型,那么一定要使用新式转型。
  • 相关阅读:
    Debian 9 更换源
    MySqlDataAdapter.Fill() 报异常‘给定关键字不在字典中’的解决方案
    阿里云函数计算 .NET Core 初体验
    TimeSpan 的 Milliseconds 和 TotalMilliseconds 有啥区别?
    使用 gitee 托管你的 go 模块
    markdown的css样式(自己写的)
    markdown的流程图实现和代码语法着色
    Python元组与字典详解
    centos7的防火墙(firewalld)
    centos7 安装java和tomcat9
  • 原文地址:https://www.cnblogs.com/-wang-cheng/p/4867321.html
Copyright © 2011-2022 走看看