我有一个简单的Trace
类,用于记录进入和退出方法:
#include <iostream>
class Trace
{
public:
Trace() {std::cout << "Enter" << std::endl;}
~Trace()
{
std::cout << "Exit" << std::endl;
}
};
void foo()
{
Trace trace;
std::cout << "foo..." << std::endl;
}
int main()
{
foo();
return 0;
}
输出:
输入
烟草工业
退出
现在我希望能够启用/禁用跟踪。所以我会做这样的事情:
#include <iostream>
class Trace
{
public:
Trace() {std::cout << "Enter" << std::endl;}
~Trace()
{
std::cout << "Exit" << std::endl;
}
static bool enabled;
};
bool Trace::enabled = false;
void foo()
{
if(Trace::enabled)
Trace trace;
std::cout << "foo..." << std::endl;
}
int main()
{
Trace::enabled = true;
foo();
return 0;
}
问题是现在trace
实例的范围限定为if statement
,因此产生了以下输出:
输入
退出
FOO ...
有没有办法在后一种情况下获得正确的输出,而不使用智能指针?如果禁用跟踪,我希望尽可能减少开销。
P.S。请注意,我的真实世界Trace
课程包含更多行,而不仅仅是“输入”和“退出”。
P.S.2 由于性能方面的考虑,如果禁用跟踪,我不希望在堆栈上创建trace
实例。
答案 0 :(得分:4)
有没有办法在后一种情况下获得正确的输出,而不使用智能指针?如果禁用跟踪,我希望尽可能减少开销。
现代编译器完全优化简单的智能指针。你应该随意使用RAII和智能指针,这在你的代码中是有意义的。编码干净清晰,避免像这样的微观优化,因为它们几乎从不帮助并经常使事情变得更糟。
答案 1 :(得分:2)
为什么不在Trace构造函数和析构函数中启用测试?
答案 2 :(得分:1)
将您的Trace
课改写为
class Trace
{
public:
Trace()
{
if(Trace::enabled)
std::cout << "Enter" << std::endl;
}
~Trace()
{
if(Trace::enabled)
std::cout << "Exit" << std::endl;
}
static bool enabled;
};
bool Trace::enabled = false;
只创建没有if
的变量:
void foo()
{
Trace trace;
std::cout << "foo..." << std::endl;
}
答案 3 :(得分:1)
除了将启用跟踪的检查放入Trace类的建议之外,还有Tom already suggested,
是否可以在不使用指针的情况下将变量的范围扩展到if语句之外?
你不应该试试这个。即使使用指针,也无法扩展变量的范围限制。 (好吧,只是为了记录,在if
条件中声明的变量的范围也包括else
子句,因此也链接else if
s。)
即使我认为这种追踪助手
class Trace
{
public:
Trace(const char* scope): m_scope(scope) {
out("enter ");
}
~Trace() {
out("leave ");
}
const char* m_scope;
static void out(const char* s) {
if (enabled) {
std::cout << s << m_scope << std::endl;
}
}
static bool enabled;
};
bool Trace::enabled = false;
对于跟踪程序的控制流似乎很方便,如果发生一些异常,您可能更愿意错过leave
跟踪输出。正如我在用这种方法试验一段时间后发现的那样,最好添加普通的跟踪命令。
答案 4 :(得分:1)
放置在堆栈上的对象具有代码,用于将它们放置在编译器在编译时创建的位置。因此,确保不在堆栈上创建对象的唯一方法是在编译时执行此操作。在运行时无法实现这一目标。
现在假设您确实需要优化跟踪对象(您已经对程序进行了分析),实现所需内容的一种方法是使用宏(由前处理器评估)汇编) - 类似于:
#define TRACE_ON // comment this to disable Trace
#ifdef TRACE_ON
#define TRACE() Trace trace
#else
#define TRACE()
#endif
然后像:
一样使用它void foo()
{
TRACE();
std::cout << "foo..." << std::endl;
}
答案 5 :(得分:0)
你想要这样的东西:
public void deleteModel() {
try {
service.deleteOemModel(selectedModel.getId());
models= service.getOemModels();
} ...
}