C++:将控制台输出存储在宏中是否更好?
C++: Is it better to store a console output in a macro?
我刚开始接触 C++ 的一些基础知识,但我意识到了两件事:
- 宏和函数的区别在于宏是预处理的,而函数是后编译的
- 在我读过的每一段代码中(还有一些带有定义的宏),没有人为控制台输出定义过宏
现在我的问题是,你应该做这样的事情吗?
没有宏:
//...
cout << "This is a test";
cout << "This is another test";
cout << "This is a third test" << " with two strings in one";
//..
使用宏:
#define OUTP(x) (cout << x)
//...
OUTP("This is a test");
OUTP("This is another test");
OUTP("This is a third test" + " with two strings in one");
//...
首先,我看不出有什么大的区别,除了我不会对宏感到困惑,因为通常“<<”是位移位,但这里它用于插入,而 "OUTP(" Test")" 对我来说看起来更好,因为它像普通方法一样工作。
但我从未见过有人使用它,这背后有什么原因吗?
我正在使用宏进行输出。它比常规输出有一定的优势,即:
- 您最近可以在一处更改所有输出 - 在宏定义处。例如,如果您想在所有输出前加上时间戳,使用宏,您只需更改一次宏。
- 您可以引入输出级别,例如
DEBUG
或 INFO
或 ERROR.
根据给定的输出级别(例如 ERROR
),您的匹配输出将被编译(例如 ERROR
和 FATAL_ERROR
)并执行,所有其他不相关的输出(例如 DEBUG
)甚至不会被编译,也不会包含在二进制代码中。而且,很多IDE甚至会将不相关的代码行变灰。
- 您还可以在宏中引入可变数量的输入参数、代码行号、编译日期和时间等。甚至使用互斥体进行多线程输出,因为
cout << "first" << "second";
不是线程安全的(另一个线程可以在您的 "first"
和 "second"
字符串之间输出一些东西)。
- 等Internet 上有很多关于此主题的文章。
"Better" 是一个非常模糊的术语,它实际上取决于您要实现的目标。
每个实施决定都有利有弊,所以具体取决于单个项目。
据我所知,抽象化宏背后的输出的优点可能是:
- 更简单的方法来替换输出方法以支持更易于管理的日志记录结构以备不时之需
- 减少打字
- 如果宏负责添加一些常见的格式设置选项,则更加统一
缺点可能是:
- 你失去了灵活性,因为宏不可避免地不允许某些直接使用 cout 允许的操作
- 您添加了一个间接层并摆脱了该语言的常见做法。有语言经验的人上手cout会比较快,不然就得自己去找宏的内容,习惯了。
肯定有其他原因支持或反对这样的选择,但最终我认为没有正确的选择。
P.S。
so confused with the macro, cause normally "<<" is bitshifting, but here it's used for insertion,
虽然这当然是一个很好的理由,但我建议您从另一方面看。 "bitshifting" 输出运算符是 C++ 中常见的模式,因此由于 operator overloading
,您应该开始更加灵活地解释运算符
我刚开始接触 C++ 的一些基础知识,但我意识到了两件事:
- 宏和函数的区别在于宏是预处理的,而函数是后编译的
- 在我读过的每一段代码中(还有一些带有定义的宏),没有人为控制台输出定义过宏
现在我的问题是,你应该做这样的事情吗?
没有宏:
//...
cout << "This is a test";
cout << "This is another test";
cout << "This is a third test" << " with two strings in one";
//..
使用宏:
#define OUTP(x) (cout << x)
//...
OUTP("This is a test");
OUTP("This is another test");
OUTP("This is a third test" + " with two strings in one");
//...
首先,我看不出有什么大的区别,除了我不会对宏感到困惑,因为通常“<<”是位移位,但这里它用于插入,而 "OUTP(" Test")" 对我来说看起来更好,因为它像普通方法一样工作。
但我从未见过有人使用它,这背后有什么原因吗?
我正在使用宏进行输出。它比常规输出有一定的优势,即:
- 您最近可以在一处更改所有输出 - 在宏定义处。例如,如果您想在所有输出前加上时间戳,使用宏,您只需更改一次宏。
- 您可以引入输出级别,例如
DEBUG
或INFO
或ERROR.
根据给定的输出级别(例如ERROR
),您的匹配输出将被编译(例如ERROR
和FATAL_ERROR
)并执行,所有其他不相关的输出(例如DEBUG
)甚至不会被编译,也不会包含在二进制代码中。而且,很多IDE甚至会将不相关的代码行变灰。 - 您还可以在宏中引入可变数量的输入参数、代码行号、编译日期和时间等。甚至使用互斥体进行多线程输出,因为
cout << "first" << "second";
不是线程安全的(另一个线程可以在您的"first"
和"second"
字符串之间输出一些东西)。 - 等Internet 上有很多关于此主题的文章。
"Better" 是一个非常模糊的术语,它实际上取决于您要实现的目标。
每个实施决定都有利有弊,所以具体取决于单个项目。
据我所知,抽象化宏背后的输出的优点可能是:
- 更简单的方法来替换输出方法以支持更易于管理的日志记录结构以备不时之需
- 减少打字
- 如果宏负责添加一些常见的格式设置选项,则更加统一
缺点可能是:
- 你失去了灵活性,因为宏不可避免地不允许某些直接使用 cout 允许的操作
- 您添加了一个间接层并摆脱了该语言的常见做法。有语言经验的人上手cout会比较快,不然就得自己去找宏的内容,习惯了。
肯定有其他原因支持或反对这样的选择,但最终我认为没有正确的选择。
P.S。
so confused with the macro, cause normally "<<" is bitshifting, but here it's used for insertion,
虽然这当然是一个很好的理由,但我建议您从另一方面看。 "bitshifting" 输出运算符是 C++ 中常见的模式,因此由于 operator overloading
,您应该开始更加灵活地解释运算符