2011-10-06 216 views
0

在两个不同文件(A.cpp,Ah,B.cpp,Bh)中,我有两个相同类的版本,所有文件中类的名称相同但内部实现不同。在不同文件中具有相同名称的不同类版本

我的想法是通过更改#include中的.h文件的名称从一个版本切换到另一个版本,所以我不应该更改代码中的其他任何东西(两个版本的方法都有相同的签名和相同的属性)

Ah和Bh从不包括在同一时间。

问题是无论什么包括我总是使用的文件执行一个版本。我知道,当我包含B.h时,至少它是编译的(通过在编译时显示一些代码错误)

可以这样做吗?或者这是违反C++的一些规则?我认为这不应该违反One Definition Rule,因为我不同时使用A.h和B.h。

+0

问题是你如何链接目标文件?只是调整包括不起作用。 – pmr

+2

如果你包含B.h并且链接到B.o,你应该没问题。你如何链接?但是如果这个班级的api是一致的,那么A.h和B.h应该是相同的;他们为什么不同? –

+0

你包含的头文件不会像你链接的实际代码那么重要。 – Joe

回答

2

解决方案是不要将旧文件链接到最终的可执行文件中。这样只有新的实施将可用。

0

如果头文件是相同的,只需要一个头文件和两个不同的实现文件就更容易了。这会将你的问题减少到只连接正确的目标文件。这也可以减少你的标题出现分歧时出现细微错误的机会。

当然,更好的解决方案是,不依赖于构建系统,而是使用语言工具在编译时更改代码,如模板。

+1

为什么模板会更好?版本管理是构建系统最好管理的典型案例。 –

+0

@詹姆斯我没有印象,他有两个不同的版本,但实际上只是两个不同的接口实现。 – pmr

2

我经常做的是将版本打包到命名空间中,然后使用它。 沿线的一些东西:

namespace Xyz_A { // In A.h 
// Define version A 
} 

namespace Xyz = Xyz_A; 

;在B.h中,改为使用_B

这样,你会在你的程序写Xyz::...,但外部 符号将有Xyz_AXyz_B错位放进去。但在我的 选项中,这实际上更能防止错误。我会在我的makefiles中安排 的东西,这样A.hB.h 之间的任何开关也会导致可执行文件链接到相应的库,而不是针对其他文件。

+0

事实上,把两个版本在不同的命名空间可以让你编译类的两个版本到同一个可执行文件。除了简化构建过程之外,它还允许您在各个版本之间编写运行时切换(这对于根据配置文件或命令行中的设置选择类版本可能很有用)。 –

+0

@AndréCaron在运行时不能在名称空间之间切换。命名空间纯粹是编译和链接时间解析。 (我用的是不同的命名空间来检测错误:编译对一个版本,而像,动态或其他方式,对另一个。) –

+0

当然你也可以不是。然而,你可以写一个简单的开关,如'回报(use_version_A:新Xyz_A ::富():新Xyz_B ::富());'。如果您使用构建过程将其切换出来,则无法完成此操作。 –

0

您将需要加载正确的库以匹配头文件。

我建议寻找代理设计模式,以便您可以包括类A和B.然后,您可以使用代理来选择在运行时使用哪个类函数。

http://en.wikipedia.org/wiki/Proxy_pattern

相关问题