对于给定的类,有时需要跟踪对构造函数/析构函数的调用。
一个明显的方法是在这些方法中添加一些痕迹,但是对于要检测的类来说通常是乏味且具有侵入性的。一种可能的方法是继承一些
TraceConstructor
结构:
#include <iostream>
template<auto& OUTPUT>
struct TraceConstructor
{
TraceConstructor () { OUTPUT << "default constructor\n"; };
~TraceConstructor () { OUTPUT << "destructor\n"; };
TraceConstructor ([[maybe_unused]] TraceConstructor const& o) { OUTPUT << "copy constructor\n"; };
TraceConstructor ([[maybe_unused]] TraceConstructor && o) { OUTPUT << "move constructor\n"; };
};
struct A : TraceConstructor<std::cout>
{
int n_;
A(int n) : n_(n) {}
};
int main()
{
A a1 {4};
A a2 = a1;
A a3 = std::move(a1);
}
问题:不是重新发明轮子,是否有一些像这样的惯用功能(在
std
,boost
,其他...)并且比这种天真的(可能不完整)方法更完整?
注意: 我在这里只关注构造函数/析构函数,但显然也可以考虑赋值运算符。
您可以使用
__PRETTY_PRINT__
宏来实现此目的。例如:
#define PRETTY() { std::cout << __PRETTY_FUNCTION__ << '\n'; }
template<auto& OUTPUT>
struct TraceConstructor
{
TraceConstructor () PRETTY()
~TraceConstructor () PRETTY()
TraceConstructor ([[maybe_unused]] TraceConstructor const& o) PRETTY()
TraceConstructor ([[maybe_unused]] TraceConstructor && o) PRETTY()
};
输出:
TraceConstructor<OUTPUT>::TraceConstructor() [with auto& OUTPUT = std::cout]
TraceConstructor<OUTPUT>::TraceConstructor(const TraceConstructor<OUTPUT>&) [with auto& OUTPUT = std::cout]
TraceConstructor<OUTPUT>::TraceConstructor(TraceConstructor<OUTPUT>&&) [with auto& OUTPUT = std::cout]
TraceConstructor<OUTPUT>::~TraceConstructor() [with auto& OUTPUT = std::cout]
TraceConstructor<OUTPUT>::~TraceConstructor() [with auto& OUTPUT = std::cout]
TraceConstructor<OUTPUT>::~TraceConstructor() [with auto& OUTPUT = std::cout]