上善若静水

while(effort=true){success++;}

   :: 首页 :: 联系 :: 聚合  :: 管理
  9 Posts :: 10 Stories :: 11 Comments :: 0 Trackbacks

留言簿(1)

搜索

  •  

积分与排名

  • 积分 - 41860
  • 排名 - 515

最新随笔

最新评论

阅读排行榜

评论排行榜

                                                                                                      <<C++ Primer Plus>>Fifth Edition     
 1.构造函数
      构造函数不能是虚函数。创建派生类对象时,将调用派生类的构造函数,而不是基类的构造函数,然后,派生类的构造函数将使用基类的一个构造函数,这种顺序不同于继承机制。因此,派生类不继承基类的构造函数,所以将类构造函数声明为虚拟的没有什么意义.
      2.析构函数
      析构函数应当是虚函数,除非类不用做基类.例如,假设Employee是基类,Singer是派生类,并添加一个char*成员,该成员指向由new分配的内存.当Singer对象过期时,必须调用~Singer()析构函数来释放内存.
      请看下面代码:
      Employee *pe = new Singer; // legal because Employee is base for Singer
      .........
      delete pe;                             // ~Employee() or ~Singer()?
      如果使用默认的静态联编,delete语句将调用~Employee()析构函数.这将释放由Singer对象中的Employee部分指向的内存,但不会释放新的类成员指向的内存.但如果析构函数是虚拟的,则上述代码将先调用~Singer()析构函数释放由Singer组件指向的内存,然后,调用~Employee()析构函数来释放由Employee组件指向的内存.
      这意味着,即使基类不需要显示析构函数提供服务,也不应依赖于默认构造函数,而应提供虚拟析构函数,即使它不执行任何操作:
       virtual ~BaseClass(){}
      3.  友元
      友元不能是虚函数,因为友元不是类成员,而只有成员才能是虚函数.如果说由于这个原因引起了设计问题,可以通过让友元函数使用虚拟成员函数来解决.
      4.没有重新定义
      如果派生类没有重新定义函数,将使用该函数的基类版本.如果派生类位于派生链中,则将使用最新的虚函数版本,例外的情况是基类版本是隐藏的.
      5.重新定义隐藏方法
      假设创建了如下所示的代码:
   class Dwelling
   {
         public:
               virtual void showperks(int a) const;
               .....
    };
    class Hovel: public Dwelling
    {
      public:
            virtual void showperks() const;
      ........
      };
      这将导致问题,可能会出现类似于下面这样的编译器警告:
      Warning: Hovel :: showperks(void) hides Dwelling::showperks(int)
      也可能不会出现警告.但结果怎么样,代码将具有如下含义:
      Hovel trump;
      trump.showperks();  // valid
      trump.showperks(5);   //invalid
      新定义将showperks()定义一个不接受任何参数的函数.重新定义不会生成函数的两个重载版本,而是隐藏了接受一个int参数的基类版本.简而言之,重新定义继承的方法并不是重载.如果在派生类中重新定义函数,将不是使用相同的函数特征覆盖基类声明,而是隐藏同名的基类方法,不管参数特标如何.
      这引出两条经验规则:第一,如果重新定义继承的方法,应确保与原来的原型完全相同,但如果返回类型是基类引用或指针,则可以修改为指向派生类的引用或指针(这种例外是新出现的).这种特征被称为返回类型协变(covariance of return type),因为允许返回类型随类类型的变化而变化:
class Dwelling
{
public:
// a base method 
      virtual Dwelling &build(int n);
      ......
};
class Hovel : public Dwelling
{
public:
// a derived method with a covariant return type
      virtual Hovel &build(int n); // same function signature
   .........
};
注意,这种意外只适用返回值,而不适用于参数
第二,如果基类声明被重载了,则应在派生类中重新定义所有的基类版本.
class Dwelling
{
public:
//three overloaded showperks()
      virtual void showperks (int a) const;
      virtual void showperks (double x) const;
      virtual void showperks() const;
      ........
};
class Hovel: public Dwelling
{
public:
// three redefined showperks()
      virtual void showperks(int a) const;
      virtual void showperks(double x) const;
      virtual void showperks() const;
      ..........
};
      如果只重新定义一个版本,则另外两个版本将被隐藏,派生类对象将无法使用它们.注意,如果不需要修改,则新定义可只调用基类版本.

posted on 2006-10-13 12:16 上善若静水 阅读(704) 评论(0)  编辑 收藏 引用 所属分类: 知识点滴

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理