I want to create an unknown number of objects each with a specific object name inside the main-method at runtime. The objects should be existent until the program ends (main-method ends). Note, that in my case the objects are Fields.

I thought about a solution like this:

for ( i=1 ; i <= NumberOfObjects ; i++)
{

if (i==1)
{
MyClass *ObjectName1 = new MyClass();

}

if (i==2)
{
MyClass *ObjectName2 = new MyClass();

}

.   //more if statements for more objects
.
.

} //for loop closed

Questions:

  1. I don't think this solution is good, since the number of created objects still would be limited to the if-statements within the for-loop. Any better solutions?

  2. Scope of pointers in loops: When the if-blocks are exited the pointers are out of scope. How can I access the with "new" created objects afterwards?

有帮助吗?

解决方案

Named variables are removed once the code is compiled and doesn't mean anything to you afterwards.

Looks like you need a look up table, use an std::map or std::unordered_map with string key as the name of the object.

std::map<std::string, MyClass*> variablesTable;
for ( i=1 ; i <= NumberOfObjects ; i++)
{
    std::ostringstream oss << "name" << i;
    variablesTable[oss.str()] = new MyClass();    //you actually need to check if it exists, otherwise will be overwritten.
}    

As if you want each created to run a separate code for each object, you can have a table of function objects (or just store both in a tuple) like this std::map<std::string, std::<MyClass, Func>>.

If you want to lookup just use,

MyClass* object = variablesTable[strName];
object->CallFunction();

P.S. A known trick for hash_maps is to run script before building the project to convert any literal string to int, because comparing int is faster than strings. At least I know this was used in the Uncharted series (but hardly relevant to your case).

其他提示

To elaborate on your approach, there is no need for a loop. You can simplify this to

MyClass *ObjectName1 = new MyClass();
MyClass *ObjectName2 = new MyClass();
MyClass *ObjectName3 = new MyClass();
...

The scope and the lifetime of the pointer already ends, when you leave the if statement. To access the pointers outside the if/for statements, you have to move them before the loop.

I would just use a std::vector of objects

std::vector<MyClass*> objects;
for (int i = 1; i <= NumberOfObjects; i++) {
    MyClass *p = new MyClass();
    objects.push_back(p);
}

This won't give you an individual name for each object, but is maintainable at least.

Update:

To address the concerns of leaking memory, you can also create the objects directly in the vector without an explicit new

std::vector<MyClass> objects;
for (int i = 1; i <= NumberOfObjects; i++)
    objects.push_back(MyClass());

This will give you the objects and they will be cleaned automatically, when the scope of the vector ends.

You will need something to store that objects. For example you could use a std::vector, or a std::map. You can store an unlimited number of objects (actually you're limited by your memory amount, let's say almost unlimited) inside these data structures, without caring about the memory since it's managed automatically.

EDIT: OK, that's not an answer. OP wants arbitrary object count at run time! That question may be a template meta programming one.

Use a vector to store the pointer, use a macro to define a new pointer and push it to the vector. Before ending, use the vector to free.

#include <vector>

#define DEFVAR( varname )      \
    foo* varname = new foo();  \
    v.push_back( varname )

class foo {};

int main() {

   std::vector<foo*> v;

   DEFVAR( ObjName1 );
   DEFVAR( ObjName2 );
   DEFVAR( ObjName3 );
   DEFVAR( ObjName4 );

   [ .... ]

   for ( size_t index = 0; index < v.size(); ++index ) delete v[ index ];

   return 0;

}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top