【发布时间】:2009-06-15 23:12:24
【问题描述】:
在跨平台项目中工作时,您很可能会在代码中遇到很多#ifdef 块。这实际上很烦人,并且很难阅读代码。
我想知道是否有办法隐藏那些不相关的 ifdef 块?我正在使用 Visual Studio 2005。
例如,如果您有以下代码:
#ifdef _PC_
do a
#else
do b
#endif
如果定义了_PC_,工具/插件应该只显示这个:
do A
【问题讨论】:
在跨平台项目中工作时,您很可能会在代码中遇到很多#ifdef 块。这实际上很烦人,并且很难阅读代码。
我想知道是否有办法隐藏那些不相关的 ifdef 块?我正在使用 Visual Studio 2005。
例如,如果您有以下代码:
#ifdef _PC_
do a
#else
do b
#endif
如果定义了_PC_,工具/插件应该只显示这个:
do A
【问题讨论】:
虽然我的答案并不完全符合您的要求,但这是我所知道的最好的答案。
在 Visual Studio 2005 中,可以使用大纲工具折叠 #ifdef 块的未使用部分。
想到的另一个想法是将特定于操作系统的代码分解为它们自己的文件,并使用包含#ifdef 块和代码的重要部分(即完整声明)的主文件,这些代码不会跨平台更改。
想到的另一件事是尽可能简单地将条件块的代码分组。在许多情况下,代码顺序可能并不重要,您可以将这些代码组合在一起。
如果您只想将该文件用作参考资料,可以做的另一件事是通过仅处理条件块并忽略处理条件块不需要的任何内容的预处理器运行文件。
【讨论】:
我见过(并使用过的)最简洁的方法是使用Strategy Pattern,借此您可以将特定于平台的代码抽象为一个单独的策略类。
例如。
class MyAbstractClass
{
static MyAbstractClass Create()
{
#ifdef win32
return new WindowsClass(); // this could be a shared_ptr
#else
return new PosixClass();
#endif
}
virtual method MyMethod() = 0;
}
// windows_class.cpp
class WindowsClass : public MyAbstractClass
{
virtual method MyMethod()
{
// platform specific code here
}
}
// posix_class.cpp
class PosixClass : public MyAbstractClass
{
virtual method MyMethod()
{
// platform specific code here
}
}
【讨论】:
我建议不要做你所问的事情。隐藏您的代码是多平台的这一事实很容易导致您或其他人没有意识到他们所接触的代码需要针对每个平台进行修改。
例如,如果您在 do A 行之后添加一行怎么办?你如何判断它是进入街区内部还是外部?您添加的新行也可能需要在另一部分中使用适当的备用行。或者,如果它超出了区块,您甚至可以在不知情的情况下破坏其他版本。
这可能看起来不方便,但语言就是这样。最好习惯该语言的设计方式以及其他人使用它的方式,而不是尝试根据自己的喜好修改内容。
【讨论】:
为您正在使用的每个平台设置一个解决方案,并在每个平台中定义适当的宏。在所有解决方案中包含源文件。然后遍历并折叠与当前解决方案的平台不匹配的代码部分。
Visual Studio 将保存每个解决方案的折叠部分设置,因此您将看到不同的展开代码,具体取决于您打开的项目。我认为这是存储在 *.suo 文件中的。
【讨论】:
只需使用以下预处理器指令:
#region IfDef
#ifdef PC
doSomethingCalledA();
#else
doSomethingCalledB();
#endif
#endregion
【讨论】: