Object and its class definition in one call to macro

I would like to write a macro which in the following usage defines a global object foobar

for the class defined below.

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

      

In other words, I would like the above to have the same effect as:

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

      

It is very important to specify the exact name "foobar" for the object (or at least call a reference to the corresponding object in this way). The class name is irrelevant as long as it allows the macro to be used multiple times.

This is quite tricky since the class usually needs to be defined before using it, but perhaps there is some tricky (possibly used by templates) way to achieve it?

+3


source to share


4 answers


It's very easy using the preprocessor concatenation operator ##

.

Something like:



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

      

+1


source


I in the meantime found a solution that links and initializes it with an appropriate object that somehow answers the question. I'm not sure if this is a standard complaint (it is gcc 4.6 compliant).



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!
}

      

+1


source


You can do this:

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

      

Then use it like this:

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

      

+1


source


EDIT: Added more clarification to codes.

The template solution would be as follows:

I created a template for classes that need to have a globally accessible instance when created. I think this is what you want. (I named it as Singleton declaring design pattern named) .h:

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

      

The getInstance () method will be from where you get this instance. It could be an object instead of a pointer, but I like it better because it is more versatile with you to do something more complex like changing the instance at runtime; also it allows you to instantiate an object only when it is in use, preventing the memory allocation necessary. .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;
}

      

You can implement any class you want normally and use the Singleton pattern to ensure that you always deal with the same global instance of some class. If you want, you can also use typedef for names like caliry. Defining your class:

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

typedef Singleton<foobar_impl> Foobar;

      

Then you use a template to replay the foobar_impl instance:

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

      

The problem with this solution is that the Singleton pattern will only work on classes that have an empty constructor. But so are your examples, so I think this is what you want.

0


source







All Articles