Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
244 views
in Technique[技术] by (71.8m points)

c++ - trying to force static object initialization

I am trying to initialize a static object without success. The purpose is to automatically register a factory class in a repository (which is a singleton).

I've already had a look at: How to force a static member to be initialized?

One of the comments says that (there is also an example that I've followed):

I read it up in the C++ standard (14.7.1): Unless a member of a class template or a member template has been explicitly instantiated or explicitly specialized, the specialization of the member is implicitly instantiated when the specialization is referenced in a context that requires the member definition to exist; in particular, the initialization (and any associated side-effects) of a static data member does not occur unless the static data member is itself used in a way that requires the definition of the static data member to exist.

So I'm trying to do something similar but I haven't manage to force the object initialization. Here is the code. I don't know what I'm missing. This is the template I'm using.

namespace my_lib
{
    template <typename T>
    struct FactoryHelper
    {
        FactoryHelper ();
        static FactoryHelper<T> _helper;
    };
}

And this is the macro that the user of the library would use to define the factory class and, at the same time, register an object in the repository:

#define CREATE_FACTORY(ClassName)
namespace my_lib
{
    class ClassName##Factory;
    template<> FactoryHelper<ClassName##Factory>::FactoryHelper () { std::cout << "object initialized!" << std::endl; }
    template<> FactoryHelper<ClassName##Factory> FactoryHelper<ClassName##Factory>::_helper;
    struct ClassName##Factory : public FactoryBase<ClassName> {
      ...
    };
} 

The previous code is defined in a header file (Factory.h).

In a .cpp file (Example.cpp), I have:

CREATE_FACTORY(UnitTestExample)
...

When I execute the program, I cannot see the message that the constructor prints when it is invoked. Any help is more than welcome.

Thanks in advance.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

This is a tricky area of C++. What you've done is to try to define the static member here:

template<> FactoryHelper<ClassName##Factory> FactoryHelper<ClassName##Factory>::_helper;

but this is actually a declaration and not a definition. For C++ to treat it as a definition you have to pass something to the constructor. Typically, this is the value you want to initialize it to:

template<> FactoryHelper<ClassName##Factory> FactoryHelper<ClassName##Factory>::_helper = FactoryHelper<ClassName##Factory>();

But in your case, you want this to be a singleton, so you probably don't want it to be copyable. In that case, you need some dummy parameter:

template<> FactoryHelper<ClassName##Factory> FactoryHelper<ClassName##Factory>::_helper(0);

and you have to modify your constructor appropriately:

template<> FactoryHelper<ClassName##Factory>::FactoryHelper (int) { std::cout << "object initialized!" << std::endl; }

Here is the complete working example:

#include <iostream>

namespace my_lib
{
    template<typename> struct FactoryBase { };
    template <typename T>
    struct FactoryHelper
    {
        FactoryHelper (int);
        static FactoryHelper<T> _helper;
    };
}

#define CREATE_FACTORY(ClassName)
namespace my_lib
{
    class ClassName##Factory;
    template<> FactoryHelper<ClassName##Factory>::FactoryHelper (int) { std::cout << "object initialized!" << std::endl; }
    template<> FactoryHelper<ClassName##Factory> FactoryHelper<ClassName##Factory>::_helper(0);
    struct ClassName##Factory : public FactoryBase<ClassName> {
    };
} 

struct UnitTestExample {
};

CREATE_FACTORY(UnitTestExample);

int main(int argc,char **argv)
{
  return 0;
}

That said, using some of the suggestions in the other answers may be a better design decision.

More information on the explicit specialization declaration vs. definition can be found here: static member initialization for specialized template class


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...