如何在C ++中模拟析构函数调用的逆序?

时间:2014-11-09 16:54:15

标签: c++ destructor destroy

我想将一些信息从基础对象传播到派生对象。只有一个问题:我想在对象破坏时这样做。

具体任务是报告时间指标:

class Counter {
  using Clock = std::chrono::steady_clock;
  using TimePoint = std::chrono::time_point<Clock>;
  TimePoint start_ = Clock::now();

 public:
  ~Counter() { /* Propagate |start_| and |Clock::now()| */ }
};

不能这样做,因为派生的虚方法Report()已经消失了:

class Counter {
  using Clock = std::chrono::steady_clock;
  using TimePoint = std::chrono::time_point<Clock>;
  TimePoint start_ = Clock::now();

  virtual void Report(TimePoint, TimePoint) = 0;

 public:
  virtual ~Counter() { Report(start_, Clock::now()); }
};

我认为这种任务有某种设计模式 - 你能建议吗?

3 个答案:

答案 0 :(得分:1)

在析构函数树运行之前让基类提供功能在引用计数实现中非常常见,但同样的方法可以很容易地为您工作。

class Base
{
    using Clock = std::chrono::steady_clock;
    using TimePoint = std::chrono::time_point<Clock>;
    TimePoint start_ = Clock::now();

protected:
    virtual void ~Base();

public:
    void Release() { Report(start_, Clock::now(); delete this; }
};

现在,用户需要拨打o->Release()而不是delete o。您可能希望为您的班级专门化std::make_unique,以便自动提供正确的删除者。

答案 1 :(得分:0)

您可以将您的柜台存放在RIAA容器中,例如a std::unique_ptr,容器可以在调用容器析构函数时调用包含的计数器上的相应虚函数。 std::unique_ptr可以使用自定义删除工具。但你也可以编写自己的Wrapper。

答案 2 :(得分:0)

在构造或销毁期间,不应该尝试调用虚函数。执行基类析构函数时,只知道基类类型!

您的设计可以修改如下:

  1. 创建一个数据结构,其中包含执行Report的所有必要信息,我们称之为ReportInfo。
  2. class ReportInfo {
      // all the information needed to be passed
    }
    
    1. 更改基类Counter,使其不再是抽象,添加ReportInfo类型的受保护成员信息,并使用ReportInfo信息成员使报告成为非虚函数。
    2. class Counter {
        using Clock = std::chrono::steady_clock;
        using TimePoint = std::chrono::time_point<Clock>;
        TimePoint start_ = Clock::now();
      
        protected:
           // this protected member contains the information needed for the Report
           ReportInfo info;
      
        // forward the Report to the version using the ReportInfo
        void Report(TimePoint s, TimePoint e) {
          Report(info, s, e);
        } 
        // doing the Report work
        void Report(ReportInfo, TimePoint, TimePoint);
      
       public:
        // a ctor has to be implemented
        Counter();
      
        virtual ~Counter() { Report(start_, Clock::now()); }
      };
      
      1. 在派生类的析构函数中,根据需要设置基类的ReportInfo,例如,派生类SpecialCounter(使用静态函数创建报告):
      2. virtual ~SpecialCounter() {
            ReportInfo _info = SpecialCounter::createReportInfo();
            // set the base class member
            info = _info;
        }
        

        参考是Effective C++

        祝你好运!