使用命名空间来避免名称冲突

时间:2012-05-15 19:54:09

标签: c++ namespaces

我正在编译我使用的一个项目,这次使用VS2010,只是为了发现windows.h中的一个包含有一个typedef INPUT,它与我已经拥有的代码中的导出const字符串冲突了

// winuser.h(第5332行)

typedef struct tagINPUT {
    DWORD   type;

    union
    {
        MOUSEINPUT      mi;
        KEYBDINPUT      ki;
        HARDWAREINPUT   hi;
    };
} INPUT, *PINPUT, FAR* LPINPUT;

// foo.h中

//stuff here
extern FOO_DLL_API const string INPUT;

现在,我没有在违规的.cpp中使用INPUT(我没有拥有大部分代码),并且试图将影响降到最低,我做了以下事情:

// MYFILE.CPP

#include <foo.h>
namespace windowsLib {    //I added this
#  include <windows.h>
}

using namespace windowsLib;

到目前为止,这种方法运行良好,但我想问你是否看到这种方法的潜在问题,或者你有更好的建议。

修改

我感谢所有关于为什么这是一个坏主意的评论和解释。我从你的评论中得到的是我应该改变foo.h并将内容放入命名空间。但是,通过这样做,我会影响几十个文件,还有一些,现在需要命名空间资格。

有没有办法以“正确的方式”执行此操作而不触及所有这些文件?

如果我是代码的所有者,我会做这个改变并完成它,但我必须提出一个解决方案,并将其批准并分配给某人等。所以如果更改是更容易的话最小的。

编辑2:

我的最终建议是将课程分成两部分,如下所示:

// stub.cpp

#include <windows.h>

//Implementation of wrapper methods

// stub.h

class stub {
    //public wrapper methods
}

// MYFILE.CPP

#include <stub.h>
#include <foo.h>    

我接受Benlitz的回答,因为这个建议也可以解决我目前面临的当前最小影响限制的问题。不过,谢谢大家的意见。

4 个答案:

答案 0 :(得分:3)

不仅语言不允许(假设标准头将包含在命名空间中),还存在调用<windows.h>中声明的任何函数并发现该问题的问题链接器将在命名空间windowsLib中查找它们。

只是不起作用!

答案 1 :(得分:2)

至少这似乎是一个坏主意。

1)如果这实际上是您的代码,添加命名空间没有任何好处,因为您在下一行有using namespace windowsLib;。无论如何,INPUT不会有歧义吗?

2)您可能包含使用来自windows.h的内容的其他标头,并且不会使用正确的符号。想象一下,包括一个标题,它定义了一个返回INPUT的函数。怎么会有效?

我建议你安全地播放,只需重命名你的类型。

答案 2 :(得分:1)

如其他答案中所解释的那样,这是一个坏主意。以下是一个可以帮助您解决问题的想法:

// MYFILE.CPP

#define INPUT UnusedSymbol
#include "foo.h"
#undef INPUT

#include "windows.h"

这可能有效,因为INPUT是foo.h中的一个外部变量,所以只要你不在myfile.cpp中使用它,编译器和链接器都不会关心它。 UnusedSymbol是一个虚拟名称,您可以编写源中未使用的任何名称。

答案 3 :(得分:1)

在windows.h周围放置命名空间听起来很危险。它可能会隐藏你需要的东西。除了你在下一行导入命名空间之外。

我会尽快将名称空间放在foo.h:

namespace fooLib {
#include "foo.h"
}

using fooLib;

我想这只是将问题从操作系统代码转移到foo代码,但这对我来说似乎更安全。

另一种方法可能是在foo周围构建一个包装器,它调用foo函数并在一个单独的小包装器库中返回foo globals。一个不需要windows.h。您可以将此包装器放在命名空间中以防止再次发生这种情况。

我假设您能够重命名foo.h中的内容或将fooLib命名空间放在foo.h中的内容中。

如果您可以触摸foo.h,最好在foo.h中重命名INPUT或将foo.h内容放在自己的命名空间中。我认为fooLib命名空间会带来很大的(明显的)好处。