【发布时间】:2011-01-17 17:10:12
【问题描述】:
#define dItemName L"CellPhone"
【问题讨论】:
-
您可能想查看 Scott Meyers 的“Effective C++”——我认为第 3 版是最新的。他在解决这个问题和许多其他类似的 C++ 问题方面做得很好。
-
这个
dItemName有什么用处?添加示例。
标签: c++
#define dItemName L"CellPhone"
【问题讨论】:
dItemName有什么用处?添加示例。
标签: c++
将其定义为常量变量。这是一种很好的编程习惯。
const wchar_t *dItemName = L"CellPhone";
如果您以后需要知道字符串的长度,则将其定义为数组:
const wchar_t dItemName[] = L"CellPhone";
另外,为什么#define 不好:它将所有使用单词 dItemName 的地方转换为 L"CellPhone"。示例:
struct {
int dItemName;
} SomeStruct;
将失效:
struct {
int L"CellPhone";
} SomeStruct;
【讨论】:
* 或std::wstring?
const wchar_t dItemName[] = L"CellPhone";。几乎没有区别,但有一些区别。特别是,编译器知道数组的大小,但不知道指针指向的元素数量。
有趣的是,我找不到一个问题来指出所有的缺点,甚至这个主题之前肯定已经讨论过。
首先,在C(不是C++)中,这是声明常量的方式。这也解释了为什么这么多 C++ 开发人员仍在使用它:当他们来自 C 背景或曾被具有 C 背景的人教过/学习过时,他们往往会重现这种 C-ish 行为。
然而,在 C++ 中,我们有更好的工具。
#define 没有定义常量,它定义了一个宏
宏不知道作用域:
它们是预处理工具:预处理器不了解底层语言的规则(无论是 asm、C 还是 C++),并且总是会扩展它所拥有的符号而不考虑范围。
因此,通常建议使用一组特定的符号来区分宏。人们通常使用ALL_CAPS 符号,但您需要记住:
为了符合 C++ 标准。
宏不是类型安全的。
正如我所说,预处理器忽略了底层语言规则,因此以下内容并不奇怪:
#define FOO "foo"
int main(int argc, char* argv[])
{
if (FOO) { ... }
return 0;
}
另一方面,使用正确的类型可以防止这种无意的错误:
std::string const Foo = "foo";
结论?
如果你愿意,你可以使用#define,只是你做额外的工作而不是编译器,但这是你的决定。个人:我很懒:)
【讨论】:
__FILE__/__LINE__,宏是必要的,因为函数,即使是内联的,也会使用它们定义的__FILE__/__LINE__,而不是从点-使用。类似地,对于 C(在带有 RAII 和异常的 C++ 中不那么重要),对函数中的清理部分的名称有一个项目范围的约定,带有检查返回的宏和goto 清理部分不是糟糕(替代方案是箭头模式),并且只有宏可以goto 在使用点范围内。
#define 的一个主要问题是它在语言本身之外,因此不限于给定范围。您将在翻译单元中的任何位置、所有命名空间、类、函数等中替换 dItemName。
我会用const std::wstring dItemName = L"CellPhone";替换它
【讨论】:
#define 是定义宏的预处理器指令。在您的情况下,宏 dItemName 具有值 L"CellPhone"。
宏不好主要是因为它们在实际代码之前被处理。这意味着它们不受范围和 C++ 语法规则的约束。如果你在某处有一个名为 dItemName 的变量,那么事情可能不会起作用:因此你会遇到难以理解的编译错误。
解决方案是将dItemName 声明为变量(在本例中为const 变量)。
【讨论】:
指出将做他们发明的事情定义为失败是-将切割归咎于刀。
如果你没有正确地用 UPPERCASE_NAMES 命名你的定义,你会遇到麻烦,但是如果你不能自律你的工作方式,那么在 C 中你会遇到这些麻烦。
您不能使用 const 生成动态重新排列系统,因此它不适合任何为使用而定制的预编译的嵌入式应用程序。Const 只能分配预评估常量,因此甚至不能分配其他 const 表达式。
工具不会因为不服从 OO 范式而突然变得无用。就功能而言,Const 不等于替换。
【讨论】:
因为您刚刚创建的预处理器宏会污染每个名称范围。它们随处可用,并且不遵循标准命名范围规则。因此,使用这样的宏,int dItemName = 5; 之类的代码会被预处理器处理为int L"CellPhone" = 5;。一个常量的全局变量不会这样做。
抛开所有其他问题不谈,这是 IMNSHO 宏定义方面最糟糕的问题。
【讨论】: