我想将一些信息从基础对象传播到派生对象。只有一个问题:我想在对象破坏时这样做。
具体任务是报告时间指标:
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()); }
};
我认为这种任务有某种设计模式 - 你能建议吗?
答案 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)
在构造或销毁期间,不应该尝试调用虚函数。执行基类析构函数时,只知道基类类型!
您的设计可以修改如下:
class ReportInfo {
// all the information needed to be passed
}
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()); }
};
virtual ~SpecialCounter() {
ReportInfo _info = SpecialCounter::createReportInfo();
// set the base class member
info = _info;
}
参考是Effective C++。
祝你好运!