0

I'm trying to create objects of this class, but storage duration should be static: The program must create exactly storage_count (not more, not less) objects of type anywhere, one after another, starting from index argument value 0, and progressing up to and including storage_count - 1.

class anywhere
{
public:
    anywhere( std::string storage_duration_name, unsigned short index )
            : storage_duration_name_( std::move( storage_duration_name )), index_( index )
    {
        std::cout << "constructor " << storage_duration_name_ << ' ' << index_ << std::endl;
    }

    ~anywhere( )
    { std::cout << "destructor " << storage_duration_name_ << ' ' << index_ << std::endl; }

private:
    const std::string storage_duration_name_;
    const unsigned short index_;

    anywhere( const anywhere & ) = delete;

    anywhere( anywhere && ) = delete;
};

The problem here is that count of objects are determined at run time and may vary 0 <= count <=100. As it is impossible to create static objects of class inside of a loop(it won't create them every time, only on first iteration it is created) or recursively (which gives undefined behavior). I tried something like this but I think there may be short way of doing this.

//form main() ...

unsigned short storage_count = argv[ 2 ];//with checks focourse
unsigned short number = 0;
object_creator<anywhere>( storage_duration_name, number, storage_count );

//end of main() ...

template<class T>
void object_creator( std::string &storage, unsigned short current, unsigned short &num )
{
    if ( storage == "static" )
    {
        if ( current > num )
        {
            return;
        } else if ( current == 1 )
        {
            static T o1 = T( storage, 0 );
            object_creator<anywhere>( storage, ++current, num );
        } else if ( current == 2 )
        {
            static T o2 = T( storage, 1 );
            object_creator<anywhere>( storage, ++current, num );

        } else if ( current == 3 )
        {
            static T o3 = T( storage, 2 );
            object_creator<anywhere>( storage, ++current, num );

        } else if ( current == 4 )
        {
            static T o4 = T( storage, 3 );
            object_creator<anywhere>( storage, ++current, num );
//..... for 100 of them

Any hints or sources to read I'll appreciate that!

  • 1
    In C++ it's not possible to have varying number of static objects, determined at runtime, C++ does not work like that. The closest thing to this would be a static `std::vector`, that gets resized once to initialize it, at runtime. – Sam Varshavchik Jun 07 '20 at 13:39
  • 2
    There's a problem with your question: You say you needed the objects to be static, but you don't tell us what brings you to that conclusion. This makes your question a so-called "XY Problem". – Ulrich Eckhardt Jun 07 '20 at 13:45
  • @SamVarshavchik I tend to believe that it is immpossible, besides std::vector is dynamic one. I'm just looking for shorter way. Thanks! – Sargis Khachatryan Jun 07 '20 at 13:55
  • 1
    Static `std::vector`s exist all the time. Plenty of them everywhere. Now, the values in the vector themselves are, of course, in dynamic scope. But who cares. The vector itself is static. – Sam Varshavchik Jun 07 '20 at 13:57
  • @UlrichEckhardt I'm trying to just create automatic, static, thread_local and dynamic objects of that class. No other problems to solve here. – Sargis Khachatryan Jun 07 '20 at 13:57
  • @SamVarshavchik but problem arises when I'm trying to create `static std::vector name;` as default constructor no longer exists and same goes for copy constructor. – Sargis Khachatryan Jun 07 '20 at 14:18
  • 1
    That's a different issue. `std::list` should work, instead, which, with careful usage of `emplace`, will not require the services of a copy constructor. – Sam Varshavchik Jun 07 '20 at 14:20

2 Answers2

1

In general I also think this might be an XY-Problem, but assuming it is not, the only way seems to be to create the objects on the stack with recursion. But since these would be deallocated when the function returns, you would have to execute all of your program inside the recursive function. This is done here by passing a std::function do_main to the recursive object creator, such that it can call it inside the deepest recursive call, when all the objects are still alive. Once do_main returns, all the objects on the stack are deallocated. (For simplicity I left out the object names etc).

template<class T>
void object_creator(int number_of_objects, std::function<void()>& do_main)
{
    T object;
    if(number_of_objects > 0) object_creator(number_of_objects - 1, do_main);
    else do_main();
}
alain
  • 11,939
  • 2
  • 31
  • 51
1

I'll first say that, indeed, you might be presenting us with an "XY problem", and what you actually need is something else than a runtime-determined number of "static" instances of a class.

Regardless: It seems you want to implement something between the Singleton Pattern (single instance) to the Multiton pattern (multiple, but controlled, instances).

For the latter, have a look at this SO question:

C++ templated class implementation of the multiton pattern

and for the former, this SO question:

C++ Singleton design pattern

You should be able to implement something between them; like @SamVarshavchik suggests, it's possible you'll end up using a static protected std::vector to hold your instances.

Also, remember to consider subclasses of your class. Do you want to allow them with no instance restrictions? Count them towards the overall allowed number? Disallow them entirely with a final designator for your class? Food for thought.

einpoklum
  • 118,144
  • 57
  • 340
  • 684