在调用函数的任何位置获取文件和函数名称

时间:2012-03-10 12:58:58

标签: c++

我正在使用宏__FILE____func__来检索文件和功能位置。 我的代码结构如下......(注意我使用的是游戏引擎)

Test.h

class TestClass
{
...
void Log(int status);
...
};

Test.cpp的

...
void TestClass::Log(int status)
{
printf("%s %s %i",__FILE__,__func__, status);
}
...

我创建了一个类对象,并使用它来记录我想要的任何内容。

example.cpp

#include "Test.h"
    ...
TestClass tt;
    ...
    tt.Log((int)1);
    ...

问题是输出粘贴Test.cpp的文件和函数名称,并记下example.cpp的文件名和函数。

有没有办法解决这个问题,还是我必须一次又一次地直接使用printf语句?

由于

3 个答案:

答案 0 :(得分:2)

您无需在代码中的任何位置使用printf,但您需要使用额外参数TestClass::Log__FILE__来调用__func__

不要威胁,你可以为它创建一个宏,这样你就不必在每次调用时记下额外的参数:

#define TEST_CLASS_LOG(testClassInstance,status) \
              testClassInstance.Log((int)status, __FILE__, __func__);

而不是调用

tt.Log((int)1);

你会打电话给

TEST_CLASS_LOG(tt,1);

当然,您需要更改Log签名以考虑额外参数:

void Log(int status, const char* fileName, const char* functionName);

另外,我发现Log没有访问任何类成员,因此您可以更轻松地使其成为static

class TestClass
{
   static void Log(int status);
};

void TestClass::Log(int status, const char* file, const char* func)
{
   printf("%s %s %i", file, func, status);
}

#define TEST_CLASS_LOG(status) \
                  TestClass::Log((int)status, __FILE__, __func__);

所以,如果你这样做,你只需要打电话:

TEST_CLASS_LOG(1);

不幸的是,由于宏在运行时扩展,因此无法在不修改代码的情况下自动执行此操作。您的编译器现在看到的是:

void TestClass::Log(int status)
{
   printf("%s %s %i","Test.cpp","Log", status);
}

这就是你需要作为参数传递的文件名和函数名的原因。

答案 1 :(得分:1)

创建宏扩展以使用额外参数调用Log函数。像这样:

void Log(const char* filename, const char* funcname, int status)
{
  printf("%s %s %i",filename,funcname, status);
}

...
#define LOG(status) Log(__FILE__, __func__, status)
...


int foo() {
  LOG(3);
}

编辑:更详细的解释

此代码不会向您展示如何使用您的类的Log方法,它只是展示了将宏用于您想要的想法。

我见过的大多数日志记录实现都使用静态方法,因此不需要Logger类本身的实例。这就是为什么我没有提出一个也需要一个班级成员的宏。

答案 2 :(得分:0)

您可以为函数TestClass::Log()创建文件名和函数位置参数。该电话看起来类似于以下内容:

TestClass tt;
...
tt.Log(__FILE__,__func__,(int)1);
...