理解inline化的介入和排除 (3)

2008-02-23 05:28:35来源:互联网 阅读 ()

新老客户大回馈,云服务器低至5折

甚至在您从来没有使用函数指针的时候,未 inline 化的 inline 函数的幽灵也会时不时地拜访您,因为程式员并不必然是函数指针的唯一需求者。有时候编译器会生成构造函数和析构函数的 out-of-line 拷贝,以便他们能得到指向这些函数的指针,在对数组中的对象进行构造和析构时使用。

  事实上,构造函数和析构函数对于 inline 化来说经常是个比您在不经意的检查中所能显示出来的更加糟糕的候选者。例如,考虑下面这个类 Derived 的构造函数:

class Base {
 public:
  ...

 private:
  std::string bm1, bm2; // base members 1 and 2
};

class Derived: public Base {
 public:
  Derived() {} // Derived’s ctor is empty - or is it?
  ...

 private:
  std::string dm1, dm2, dm3; // derived members 1-3
};

  这个构造函数看上去像一个 inline 化的极好的候选者,因为他不包含代码。但是视觉会被欺骗。

  C 为对象被创建和被销毁时所发生的事情做出了各种确保。例如,当您使用 new 时,您的动态的被创建对象会被他们的构造函数自动初始化,而当您使用 delete。则相应的析构函数会被调用。当您创建一个对象时,这个对象的每一个基类和每一个数据成员都会自动构造,而当一个对象被销毁时,则发生关于析构的反向过程。假如在一个对象构造期间有一个异常被抛出,这个对象已完成构造的任何部分都被自动销毁。任何这些情节,C 只说什么必须发生,但没有说如何发生。那是编译器的实现者的事,但显然这些事情不会自己发生。在您的程式中必须有一些代码使这些事发生,而这些代码——由编译器写出的代码和在编译期间插入您的程式的代码——必须位于某处。有时他们最终就位于构造函数和析构函数中,所以我们能够设想实现为上面那个声称为空的 Derived 的构造函数生成的代码就相当于下面这样:

Derived::Derived() // conceptual implementation of
{
 // "empty" Derived ctor

 Base::Base(); // initialize Base part

 try { dm1.std::string::string(); } // try to construct dm1
 catch (...) { // if it throws,
  Base::~Base(); // destroy base class part and
 throw; // propagate the exception
}

try { dm2.std::string::string(); } // try to construct dm2
catch(...) {
 // if it throws,
 dm1.std::string::~string(); // destroy dm1,
 Base::~Base(); // destroy base class part, and
throw; // propagate the exception
}

try { dm3.std::string::string(); } // construct dm3
catch(...) {
 // if it throws,
 dm2.std::string::~string(); // destroy dm2,
 dm1.std::string::~string(); // destroy dm1,
 Base::~Base(); // destroy base class part, and
throw; // propagate the exception
}
}



标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇: 理解inline化的介入和排除 (4)

下一篇: 理解inline化的介入和排除 (2)

热门词条
热门标签