3

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

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

换句话说,我希望上面的效果与:

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

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

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

4

4 回答 4

1

它非常简单,使用预处理器连接运算符##

就像是:

#define SOMEMACRO(name) \
SomeClassPossiblyWith_##name##_InItsName name; \
class SomeClassPossiblyWith_##name##_InItsName
于 2013-02-03T19:55:09.987 回答
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!
}
于 2013-02-03T21:46:20.227 回答
1

你可以这样做:

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

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

SING (foobar, {
    public:
        int a;
    }
);
于 2013-02-03T21:47:20.370 回答
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 来命名类型名称。你的类定义:

// 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 模板只适用于具有空构造函数的类。但是你的例子也是如此,所以我认为这就是你想要的。

于 2013-02-03T22:10:37.497 回答