Object和它在一个宏定义调用中的类定义

时间:2013-02-03 19:47:28

标签: c++ macros

我想写一个宏,在下面的用法中定义了一个在它下面定义的类的全局对象foobar

SOMEMACRO(foobar)
{
public:
   int a;
};

换句话说,我希望上述内容具有与以下相同的效果:

class SomeClassPossiblyWith_foobar_InItsName
{
public:
   int a;
};
SomeClassPossiblyWith_foobar_InItsName foobar;

准确地给对象赋予“foobar”名称非常重要(或者至少以这种方式调用对正确对象的引用)。只要允许多次使用宏,类的名称就无关紧要了。

这很难,因为类通常应该在使用之前定义,但也许存在一些棘手的(可能是模板参与的)实现它的方法?

4 个答案:

答案 0 :(得分:1)

使用预处理程序连接运算符##非常简单。

类似的东西:

#define SOMEMACRO(name) \
SomeClassPossiblyWith_##name##_InItsName name; \
class SomeClassPossiblyWith_##name##_InItsName

答案 1 :(得分:1)

与此同时,我找到了一个解决方案,可以使用适当的对象进行引用和初始化,以某种方式回答问题。我不确定这是标准投诉(它符合gcc 4.6)。

template<typename T>
T &delayed_make_object()
{
    static T obj;
    return obj;
}

#define DOIT(_name) \
    class TypeFor ## _name; \
    TypeFor ## _name & _name = delayed_make_object<TypeFor ## _name>(); \
    class TypeFor ## _name


DOIT(foo)
{
    public:
    int abc;
};  

DOIT(bar)
{
    public:
    int cba;
};

int main()
{
  foo.abc=bar.cba;   // works!
}

答案 2 :(得分:1)

你可以这样做:

#define SING(classname, body) class SING_##classname \
body \
; SING_##classname classname;

然后,以这种方式使用它:

SING (foobar, {
    public:
        int a;
    }
);

答案 3 :(得分:0)

编辑:为代码添加了更多解释。

模板的解决方案如下:

我为类创建了一个模板,该模板应该在创建时具有全局访问权限的实例。我想这就是你想要的。 (我将它命名为Singleton,使用名称来设计模式) .H:

// C++ header for template Singleton
template<typename T>
class Singleton : public T {
    static Singleton<T>* instance;
    Singleton();
public:
    static Singleton<T>* getInstance();
};

getInstance()方法将从那里获得该实例。它可以是一个对象而不是一个指针,但我更喜欢这种方式,因为它更通用,你想做一些更复杂的事情,比如在运行时更改实例;它还允许仅在使用对象时实例化对象,从而防止不需要内存分配。 的.cpp:

// C++ source for template Singleton
template<typename T>
Singleton<T>* Singleton<T>::instance = NULL;

template<typename T>
Singleton<T>::Singleton()
: T()
{}

template<typename T>
Singleton<T>* Singleton<T>::getInstance()
{
    if (instance == NULL)
    {
        instance = new Singleton<T>();
    }
    return instance;
}

您可以实现任何您想要的类,并使用Singleton模板来确保您始终处理某个类的同一个全局实例。如果需要,您还可以使用typedef到caliry类型名称。 你的班级定义:

// Definition of class foobar
class foobar_impl {
public:
    int a;
};

typedef Singleton<foobar_impl> Foobar;

然后,使用模板撤消foobar_impl的实例:

int main(int argc, char** argv)
{
    Foobar *pf = Foobar::getInstance();
    return 0;
}

但是,此解决方案的问题是Singleton模板仅适用于具有空构造函数的类。但你的例子也是如此,所以我认为这就是你想要的。