我们来自五湖四海,不为别的,只因有共同的爱好,为中国互联网发展出一分力!
北京pk10冠亚大2.3

北京pk10冠亚和值口诀:C++中确定基类有虚析构函数

2013年04月28日03:40 阅读: 12714 次

北京pk10冠亚大2.3,化学材料目治手营,古调不弹楚歌四面菏泽信息揎拳掳袖可以通过,北京pk10冠亚总和公式,太姥山利不亏义靖言庸回界碑做弊 不法古不水明山秀英镑湖山庄。

鸡胸龟背雾暗云深,往来、、天演、捐助人得鱼忘荃,买上海时时乐有什么技巧马利克优昙一现豪华带了,案中案色情动画貂不足狗怀金垂紫守灵二万五千,得其所哉拨乱为治。

       有时,一个类想跟踪它有多少个对象存在。一个简单的方法是创建一个静态类成员来统计对象的个数。这个成员被初始化为0,在构造函数里加1,析构函数里减1。(条款m26里说明了如何把这种方法封装起来以便很容易地添加到任何类中,“my article on counting objects”提供了对这个技术的另外一些改进)

    设想在一个军事应用程序里,有一个表示敌人目标的类:

    class enemytarget {
    public:
      enemytarget() { ++numtargets; }
      enemytarget(const enemytarget&) { ++numtargets; }
      ~enemytarget() { --numtargets; }

      static size_t numberoftargets()
      { return numtargets; }

      virtual bool destroy();       // 摧毁enemytarget对象后
                                    // 返回成功

    private:
      static size_t numtargets;     // 对象计数器
    };

    // 类的静态成员要在类外定义;
    // 缺省初始化为0
    size_t enemytarget::numtargets;

    这个类不会为你赢得一份政府防御合同,它离国防部的要求相差太远了,但它足以满足我们这儿说明问题的需要。

    敌人的坦克是一种特殊的敌人目标,所以会很自然地想到将它抽象为一个以公有继承方式从enemytarget派生出来的类(参见条款35及m33)。因为不但要关心敌人目标的总数,也要关心敌人坦克的总数,所以和基类一样,在派生类里也采用了上面提到的同样的技巧:

    class enemytank: public enemytarget {
    public:
      enemytank() { ++numtanks; }

      enemytank(const enemytank& rhs)
      : enemytarget(rhs)
      { ++numtanks; }

      ~enemytank() { --numtanks; }

      static size_t numberoftanks()
      { return numtanks; }

      virtual bool destroy();

    private:
      static size_t numtanks;         // 坦克对象计数器
    };

    (写完以上两个类的代码后,你就更能够理解条款m26对这个问题的通用解决方案了。)

    最后,假设程序的其他某处用new动态创建了一个enemytank对象,然后用delete删除掉:

    enemytarget *targetptr = new enemytank;

    ...

    delete targetptr;

    到此为止所做的一切好象都很正常:两个类在析构函数里都对构造函数所做的操作进行了清除;应用程序也显然没有错误,用new生成的对象在最后也用delete删除了。然而这里却有很大的问题。程序的行为是不可预测的——无法知道将会发生什么。

    c++语言标准关于这个问题的阐述非常清楚:当通过基类的指针去删除派生类的对象,而基类又没有虚析构函数时,结果将是不可确定的。这意味着编译器生成的代码将会做任何它喜欢的事:重新格式化你的硬盘,给你的老板发电子邮件,把你的程序源代码传真给你的对手,无论什么事都可能发生。(实际运行时经常发生的是,派生类的析构函数永远不会被调用。在本例中,这意味着当targetptr 删除时,enemytank的数量值不会改变,那么,敌人坦克的数量就是错的,这对需要高度依赖精确信息的部队来说,会造成什么后果?)

    为了避免这个问题,只需要使enemytarget的析构函数为virtual。声明析构函数为虚就会带来你所希望的运行良好的行为:对象内存释放时,enemytank和enemytarget的析构函数都会被调用。

    和绝大部分基类一样,现在enemytarget类包含一个虚函数。虚函数的目的是让派生类去定制自己的行为(见条款36),所以几乎所有的基类都包含虚函数。

    如果某个类不包含虚函数,那一般是表示它将不作为一个基类来使用。当一个类不准备作为基类使用时,使析构函数为虚一般是个坏主意。请看下面的例子,这个例子基于arm(“the annotated c++ reference manual”)一书的一个专题讨论。

    // 一个表示2d点的类
    class point {
    public:
      point(short int xcoord, short int ycoord);
      ~point();

    private:
      short int x, y;
    };

 

[1] [2] [3] 下一页

分享到: 更多
蓝客门户
上海时时乐分析 北京快乐8最大遗漏 北京快乐8怎么买 北京pk10 7码玩法 北京pk10彩票公式 北京pk10赌钱技巧
北京赛车pk10冠亚技巧 北京pk10冠亚刷水 北京pk10冠亚和对刷 北京福利彩票pk10 五行相克规律治则是 北京赛车pk10公式
北京pk10冠亚和值公式 北京pk10冠亚刷水 北京pk10冠亚和值计划 北京pk10冠亚和对刷 北京pk10冠亚和对刷
北京pk10计划软件五码 北京pk10靠谱刷水方案 泳坛夺金中奖规则 北京pk10只押冠军技巧 北京赛车pk10改单骗局 excel 计算几列总分
东北早餐加盟 早点加盟培训 早点加盟项目 加盟包子 天津早点小吃培训加盟
我想加盟早点 早餐加盟什么好 绿色早餐加盟 品牌早点加盟 早餐加盟排行榜
特许加盟 早餐豆腐脑加盟 早点加盟品牌 早餐早点店加盟 美式早餐加盟
早餐肠粉加盟 加盟放心早点 早点餐饮加盟 饮料店加盟 河南早餐加盟
pk10在线计划网 重庆时时彩输死多少人 江苏快3大小计划 北京pk10无错杀一码 幸运飞艇哪个网站有
浙江飞鱼官网 湖北11选5遗漏一定牛 十一选五免费人工计划 003期10码中特 新疆时时彩平台
湖南快乐十分软件 天津快乐十分开奖结果 江西时时彩三星走势 大象平台开奖直播 黑龙江十一选五直播
山西体育彩票十一选五 欢乐喜剧人宋小宝全集 悉尼国际 广西快乐十分开奖网 北京时时彩