Windows API和GetClassName()?另一个名字?

时间:2009-02-24 02:44:35

标签: c++ windows api-design

我有一些代码在C ++中有一个动态类系统,它有一个名为GetClassName()的成员,一个人们可以想象的无害的名字。然而,当包含在一个带有Windows标题的大型项目中时,所有地狱都会崩溃。显然,Windows使用#define GetClassName(GetClassNameA或GetClassNameW)搞砸了所有东西,我的虚拟调用树变得一团糟,让我在黑暗中愚蠢的编译器调试中失去了一天,试图弄清楚出了什么问题。

除此之外,我诅咒微软使用这样一个非常容易冲突的#define名称(我的意思是有人应该诚实地为此拍摄!)我要求3个目的。

  1. 什么是另一个好名字 GetClassName()?
  2. 无论如何都有 解决这个问题,所以将来,其他 我的代码库的开发人员不会 遭受类似的命运
  3. 而且 后人当别人 同样遇到这个 莫名其妙的错误

4 个答案:

答案 0 :(得分:5)

  1. ClassGetName()
  2. #undef GetClassName
  3. WinAPI是一个C API。没有名称空间。其他一些平台试图通过为所有符号名称添加前缀来缓解这种情况,但最终也会崩溃。最好的选择:如果您编写的代码不依赖于Windows平台SDK标头,那么就不要#include他们

答案 1 :(得分:2)

GetWindowClassName也许?实际上,GetClassName不是这个API的坏名称,因为它与窗口类有关。真正的问题是它是一个C API声明,C声明无法引入一个不会污染全局命名空间的可重用声明。

这更像是C语言的失败而不是微软。

答案 2 :(得分:2)

Windows API充满了带有干净名称的宏,这些名称扩展为函数名称,后缀表示ASCII / UTF-16,具体取决于构建选项。如果他们用“W32”或类似的东西(OS X上的一个“NS”)作为前缀,那将是很好的,但他们选择不是为了保持API“干净”。

由于更改代码比使用API​​要容易得多,因此以下是一些建议:

1)学习Windows API(它实际上并不是那么大!),或者至少熟悉MSDN,以便在遇到无法解释的程序流时查找名称冲突。

2)在代码中使用显式范围解析(MyClass :: GetClassName())。不幸的是,这会破坏虚函数调度,所以要小心。

3)在代码中使用不同的命名约定。 MS总是使用CamelCase,所以如果你选择其他约定(get_class_name(),getClassName()等),你不会发生冲突。

4)就个人而言,我讨厌命名我的getter& setters“GetX()”和“SetX()”,但更喜欢依赖重载机制并对getter使用“xtype X()const”,对setter使用“void X(xtype newval)”。你的里程可能会有所不同,但我发现它更清洁了。从参数中可以看出get / set是显而易见的。显然,如果你使用默认参数,你必须要小心。

祝你好运!

答案 3 :(得分:2)

我会重命名该方法。

当然可以说

#include <windows.h>
#undef GetClassName

但它不干净,一个人的代码用户应该记得在调用win32函数时写:: GetClassNameW。

可以在他的班级中提供GetClassNameA和GetClassNameW方法,但这很简单。

我看到两种方法:延长或缩短名称:)

1)为子系统中的所有函数添加前缀,例如TI_(对于类型信息):

TI_GetClassName() 
TI_GetBaseClass() 
TI_IsDerivedFromClass()
etc  

2)或将它们放入某些IClass接口

interface IClass {
GetName();
GetBase(); 
IsDerivedFrom();
etc

从单一方法返回该接口,
以便GetClassName()成为

GetClass()->GetName()