将带有参数的C ++宏用于链接的代码段

时间:2011-02-27 11:38:31

标签: c++ debugging macros linker

我有一个用于加速Factory类实现的宏。 例如,要为CameraGenerator构建Factory,我会以这种方式使用宏: GENERATOR_BUILD_FACTORY_START(CameraGenerator)
... do some stuff ...
GENERATOR_BUILD_FACTORY_END(CameraGenerator)

此构建和ALST INSTANTIATE名为CameraGeneratorFactory的类。所有这些都是在.cpp文件中完成的,而不是在.h中,因此Factory的特定实例变为全局变量,但特定的工厂定义在此文件之外不可用。所有工厂都继承自基础工厂类。

问题出现在另一个.cpp我需要定义和实例化另一个特定的工厂,比如FileGeneratorFactory,所以我做

GENERATOR_BUILD_FACTORY_START(FileGenerator)
... do some other stuff ...
GENERATOR_BUILD_FACTORY_END(FileGenerator)

在DEBUG中编译时,第二次使用此宏再次执行“CameraGenerator”工厂构造函数,而不是正确的“FileGenerator”工厂构造函数,就像宏已经过预处理,编译并链接到第一个.cpp一样,它始终使用相同的参数执行。我再说一遍,只有在调试模式下编译时才会出现问题

有没有人知道这种行为?

感谢之前的

以下是宏的代码:

#define GENERATOR_BUILD_FACTORY_START(GEN_NAME) \
    class GEN_NAMEFactory : public AbstractGeneratorFactory{                             \
    public:                                                                              \
       GEN_NAMEFactory() : AbstractGeneratorFactory(){                                   \

#define GENERATOR_BUILD_FACTORY_CONF_SECTION(GEN_NAME) \
           extern GeneratorBuilder generator_builder;                                    \
           generator_builder.add_factory(#GEN_NAME, this);                               

#define GENERATOR_BUILD_FACTORY_END_CONF_SECTION(GEN_NAME) \
       }                                                                                 \
       GEN_NAMEFactory(const GEN_NAMEFactory& f) : AbstractGeneratorFactory(f){}         \
       GEN_NAMEFactory& operator=(const GEN_NAMEFactory& f){                             \
           if (this == &f) return *this;                                                 \
           AbstractGeneratorFactory::operator =(f);                                      \
           return *this;                                                                 \
       }                                                                                 \
       virtual ~GEN_NAMEFactory(){}                                                      \
       virtual Generator* build() const{                                                 \
           return new GEN_NAME();                                                        \
       }                                                                                 \
       Generator* build(const Configuration& cfg) const throw(bad_parameter) {           \
            Generator* g = 0;                                                            \

#define GENERATOR_BUILD_FACTORY_END(GEN_NAME) \
            return g;                                                                    \
        }                                                                                \
    };                                                                                   \
    GEN_NAMEFactory instance_of_GEN_NAMEFactory;

2 个答案:

答案 0 :(得分:1)

而不是GEN_NAMEFactory,您需要在宏内部使用GEN_NAME##Factory。否则,您的代码将违反ODR规则(您在两个编译单元中以不同的方式定义GEN_NAMEFactory)。这仅在调试中引起麻烦,因为仅在调试中函数未内联,并且在链接时仅使用GEN_NAMEFactory的两个冲突实现中的一个。如果您尝试在一个源文件中扩展两个工厂,则很容易看到冲突。

作为替代方案(或除此之外),您可以在工厂周围使用匿名命名空间将标识符的范围限制为一个来源。

答案 1 :(得分:-1)

不要使用这些宏,它们是邪恶的。

可能认为将通用工厂代码实现为C ++模板会很有帮助。

但是我怀疑整个事情是完全被误导的,对于那些宏来说,就像看到有人在建造飞机并使用锤子来驱动螺钉一样。然后,人们倾向于强烈怀疑使用螺丝刀而不是锤子会有所帮助。当被问及飞机是什么 时,有人会回答某个目的,即飞机绝对不是合适的解决方案。

干杯&第h。,