7

我试图在构造函数中使用__FILE__and__LINE__宏作为默认参数,但我似乎无法让宏使用正确的文件。他们不断从我的头文件中扩展。

更详细地说:我希望将对象实例化为我的类成员的文件和行号。但是我不想每次我想使用对象时都必须手动输入参数。我知道有办法做到这一点,但我无法为我的生活弄明白。我目前正在做的事情如下:

在我的头文件中:

mnNumber( float x, const char* filename = __FILE__, int linenumber = __LINE__ ): 
          value( x ), mFileName( filename ), mFunctionName( nullptr ), mLineNumber(     linenumber ), mID( 0 )

但是,FILELINE被扩展,就好像它们来自我的头文件,而不是我使用 mnNumber 的实际位置。

为了回答我为什么要这样做的问题,我想让代码读取它自己的代码页。我使用的特定值正在管理器中注册,并且允许最终用户编辑它们的值。当最终用户完成编辑该值时,该值将被写回到代码页中。所以,我需要知道价值从何而来。我还允许最终用户说他们永远不需要再次编辑此值,当他们单击该按钮时,该值将从 mnNumber 转换回浮点数,并且代码页上的类型被重写为浮点数. 或者,将……希望如此。

对我有什么建议吗?

4

3 回答 3

8

您可以使用预处理器执行此操作。创建一个扩展__LINE__并使用它的宏:

struct S {
  S(int line, const std::string& file) :
    line(line), file(file) {
  }
  std::string file;
  int line;
};

#define SCons() S(__LINE__, __FILE__)

int main () {

  S s1 = SCons();
  S s2 = SCons();
  std::cout << s1.line << "\n";
  std::cout << s2.line << "\n";
}       
于 2012-07-16T02:40:13.370 回答
2

你不能这样做——这两个宏在遇到它们时被预处理器替换,因此它们将被交换为头文件名和行号。

于 2012-07-16T02:27:37.977 回答
0

OP在编辑中写道:

这并不容易,但 R. Martinho Fernandes 让我走上了正确的道路。而且我认为它不是线程安全的,但到目前为止它仍然有效。

我想要的是能够通过将类型更改为 mnFloat 来跟踪和更新浮点数。我设置了一个定义,它在我的管理器中调用一个函数来添加文件、行和函数名称,然后将浮点数更改为我的特殊类型。在管理器内部,它们都通过 ID 链接在一起。当我调用 register 函数时,我会在内部创建一个对象来存储。在同一行,我的特殊类型也被创建了,并且它向管理器注册了自己。两个对象都使用相同类型的 ID 系统(ID 是通过从我每次创建新对象时递增的静态数字复制生成的)。由于它们出现在同一代码页上,因此 ID 始终相同,并且永远不会不同步。假设我不去多线程,我想。感觉像是作弊,但它有效:)

这是它的工作原理。我拿这个:

float test = 0.5;

我把它改成这样:

mnFloat test = 0.5;

在我的头文件中,mnFloat 的定义如下:

#define mnFloat myManager::getInstance()->register(__FILE__,__FUNCTION__,__LINE__);mnNumber

因此,代码页更改为该行上的两条指令,并且行号不会增加。它有效!

于 2016-06-27T18:33:53.347 回答