2017-02-27 73 views
3

基类不能在创建派生类对象时查看派生类中定义的宏。 [C++ 14]无法将宏定义传递到基类

Base.HPP

class Base { 
public: 
    Base() { 
     #ifndef SKIP 
     std::cout << "Bing" << std::endl; 
     #endif 
    } 
}; 

文件:Derived.HPP

#define SKIP 
class Derived : public Base { 
public: 
    Derived() {} 
}; 

所以,每当我创建派生类的对象我不希望看到在Bing输出终端,因为我已经定义了宏SKIP

但是这不会发生。看起来基类对宏观的定义很无知SKIP。有没有办法做到这一点,或者这是不可能做到这一点,没有与-DSKIP国旗编译代码?

+0

不要使用宏? – Barry

+0

包含文件通常只处理一次,因此如果在处理该点时没有定义SKIP,则不会显示“Bing”。 –

+0

宏在编译器查看代码之前进行文本替换。如果你制作[mcve],人们可能会帮助你,现在我们甚至无法判断'#include'ing * Base.HPP *之前或之后'#define'd'SKIP'是否重要。此外,您可能正在违反[ODR](https://stackoverflow.com/questions/4192170),并正在前往[UB](https://stackoverflow.com/documentation/c%2b%2b/1812/)未定义的行为#吨= 201702271913219429673)。 – nwp

回答

7

首先,不要使用宏。

其次,SKIP将用于定义岬那的Base类的声明被处理时检查 - 不是当Derived类的声明被处理,所以如果你#define它,你身在何处,它只是为时已晚。你需要的方式更早做到这一点:

#define SKIP 
#include "Base.hpp" 

class Derived : public Base { ... }; 

但要确保你定义或Base每包之前没有定义SKIP以同样的方式,或者它是一个ODR-冲突。或者直接在命令行中定义它。

但是,确实不要使用宏。通过bool

+0

如果你确实真的必须使用一个宏,那么将它命名为一个漫长而又丑陋的名字,这样它就不会与其他任何东西发生冲突, G。 “SKIP_COUT_IN_THIS_CLASS_OF_MY_SUPER_COOL_LIBRARY”;-) – zett42

1

您可以使用模板来代替宏:

template<bool skip> 
struct Base {}; 

template<> 
struct Base<false> { 
    Base() { 
     std::cout << "Bing" << std::endl; 
    } 
}; 

然后,创建Derived类时,你这样做:

struct Derived : Base<true> {}; 

如果你把true作为模板参数,它将选择另一个基类输出Bing

+0

对于downvoter:我的回答有什么问题?我试图用OP的另一种方式来实现他想要的东西。有没有办法改进我的答案? –