[c++] 小心析构函数

先上代码,很少,就两个类。

  #include <iostream>

  using namespace std;

  struct Pig
  {
      virtual void call(void)
      {
          cout << "Pig\n";
      }

  };

  struct SmallPig : public Pig
  {
      virtual void call(void)
      {
          cout << "Small Pig\n";
      }
  };

  int main(int argc, char* argv[])
  {
      Pig* p = new SmallPig;
      p->call();
      delete p;
  }

打印出什么?这个简单,了解c++的都能答对:打出 "Small Pig“,因为是虚函数嘛。

好,现在改改Pig类:

  struct Pig
  {
      Pig()
      {
          call();
      }

      ~Pig()
      {
          call();
      }

      virtual void call(void)
      {
          cout << "Pig\n";
      }

  };

再运行,就不是打出3行“Small Pig”了,而是:

Pig

Small Pig

Pig

为什么?因为构造函数和析构函数特殊,在它们里面this指针只能当成自己用(而不是当成子类),所以调用虚函数的结果是调用了父类的实现。

这个问题造成了今天的bug,花了不少时间。其实这个注意事项在《Effective c++》里是有的,我也看过,但是....开发中谁还记得那么多条条框框?还是实际犯错印象比较深刻。

有人问了:如果我把call改成纯虚函数会怎样呢?更郁闷,g++编译的时候就会提示构造函数里的call“找不到实现”!


相关文章

分类

留言:

关于文章

This page contains a single entry by DongHao published on 07 22, 2010 5:46 PM.

[kernel] linux在多核处理器上的负载均衡原理 was the previous entry in this blog.

[kernel] 如果在linux内核模块里用错锁? is the next entry in this blog.

Find recent content on the main index or look in the 存档 to find all content.