是否可以使用方法返回使用 #define 创建的变量

Is it possible to use a method to return a variable created using #define?

本文关键字:#define 创建 变量 使用方法 返回 是否      更新时间:2023-10-16

所以想象一下我有代码:

#define ID_BUTTON 1

为了给自己一个变量,以便在使用 CreateWindow() 函数创建按钮时使用。

现在,我是否可以使用一种方法返回ID_BUTTON?通常我会发现它相对容易,但我不知道我必须指定什么函数类型。

所以

1(可能吗?

2( 如果是这样,我必须使用什么功能类型?

请记住,它只是简单的代码,例如:

<function_type> getID() {
return ID_BUTTON;
}

谢谢

从技术上讲,你想要的实际上是使用 C++11 decltype

的:
#define ID_BUTTON 1
auto getID() -> decltype(ID_BUTTON)
{
    return ID_BUTTON;
}
int main()
{
    auto x = getID();
}

在那里,无需为ID_BUTTON或函数指定int

但是,您的问题的真正答案应该是:不要对常量使用宏。C++为此const(截至最近(constexpr

假设你不明白什么

#define ID_BUTTON 1

甚至做到:

#defineconstconstexprenum 语句不创建变量,而是创建常量。变量和常量都是引用程序中值的标识符。不同之处在于常量不能在运行时更改,而变量可以。

但是,#define不会创建任何普通常量。它实际上告诉编译器的一部分称为预处理器,实际上将源代码中的文本ID_BUTTON替换为字符串1。这可能很有用,这就是你必须为 C 做的,但在C++中,constexpr(在 C++11 中引入(通常更优化。请参阅Christian Hackl的回答以获取更多信息。

如果您打算使用常量将值传递给 API,这是您计划对 ID_BUTTON 执行的操作,API 通常会告诉您它期望的类型,因此您可以使用该类型,而不是让编译器确定作业的最佳类型。但是,请参阅下面我关于 Windows 中的控件标识符的讨论,因为对于ID_BUTTON的特定情况有一个问题。

如果您控制了该类型,则必须多考虑一下才能确定要使用的类型。在某些情况下,该语言的类型提升规则会让你侥幸逃脱只说1没有类型,但是如果你正在创建已知的小整数或大整数,或位字段,或浮点数,你将需要使用适当的类型名称或限定符(shortlongunsignedfloatdouble, 等(。弄清楚要去哪里需要一点时间,但是一旦你做得足够多,你就会很自然地去做。


假设您不了解 Windows 中的控件标识符的工作原理:

大多数采用控件标识符的 API 函数(如 GetDlgItem()(都将控件标识符作为int;因此您的控件标识符应具有类型 int

但是,CreateWindow()CreateWindowEx()期望控件标识符作为倒数第三个参数。此参数的类型为 HMENU 。C++不会让你把int塞进HMENU,所以你必须使用石膏:(HMENU) ID_BUTTON。(可能有一个等效的C++式演员阵容,但我不知道/忘记了它是什么。

此外,如果要使用资源文件,则必须使用 #define 语句来创建ID_xxx常量名称,因为资源文件格式没有 constconstexprenum 。在这种情况下,请继续对标识符使用 #define,将这些#define放入其自己的包含文件中,并从C++源和资源文件中#include该文件。

如果不使用资源文件,则根本不需要担心使用控件标识符;只需直接使用每个控件的HWND即可。如果需要在窗口中处理选项卡导航或其他对话框消息,仍应分配控件标识符,但除此之外,您可以直接使用 HWND s。(我忘记了选项卡导航中是否涉及控件标识符。

最后,有许多预定义的控件标识符对对话框管理器具有特殊意义。这是来自Microsoft的winuser.h:

/*
 * Dialog Box Command IDs
 */
#define IDOK                1
#define IDCANCEL            2
#define IDABORT             3
#define IDRETRY             4
#define IDIGNORE            5
#define IDYES               6
#define IDNO                7
#if(WINVER >= 0x0400)
#define IDCLOSE         8
#define IDHELP          9
#endif /* WINVER >= 0x0400 */

您自己的控件标识符应避免与这些标识符冲突;您的ID_BUTTONIDOK冲突。(如果它们确实发生冲突,您会看到奇怪的事情,例如您的控件在对话框管理器知道的键盘快捷键上激活。这个问题的规范解决方案是开始对控件标识符进行编号100(我相信Visual Studio对此负责,但我不确定(。