在运行时c ++创建具有特定对象名称的未知数量的对象

时间:2014-02-11 14:46:57

标签: c++ loops scope object-lifetime

我想在运行时在main方法中创建一个未知数量的对象,每个对象都有一个特定的对象名。在程序结束之前,对象应该存在(main-method结束)。请注意,在我的情况下,对象是Fields。

我想到了这样的解决方案:

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

问题:

  1. 我不认为这个解决方案是好的,因为创建的对象的数量仍然限于for循环中的if语句。还有更好的解决方案吗?

  2. 循环中指针的范围:当退出if块时,指针超出范围。之后如何访问“新”创建的对象?

4 个答案:

答案 0 :(得分:6)

编译代码后,命名变量将被删除,之后对您没有任何意义。

看起来你需要一个查找表,使用带字符串键的std :: map或std :: unordered_map作为对象的名称。

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

好像你希望每个创建的每个对象都运行一个单独的代码,你可以有一个函数对象表(或者只是存储在一个元组中),如std::map<std::string, std::<MyClass, Func>>.

如果你想查找只是使用,

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

P.S。 hash_maps的一个已知技巧是在构建项目之前运行脚本以将任何文字字符串转换为int,因为比较int比字符串更快。至少我知道这是在Uncharted系列中使用的(但与你的情况几乎没有关系)。

答案 1 :(得分:3)

要详细说明您的方法,不需要循环。您可以将其简化为

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

当您离开if语句时,指针的范围和生命周期已经结束。要访问if / for语句之外的指针,必须在循环之前移动它们。

我只会使用std::vector个对象

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

这不会为每个对象提供个人名称,但至少可以维护。

更新

为了解决泄漏内存的问题,您还可以直接在向量中创建对象,而无需显式的新

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

这将为您提供对象,当向量范围结束时,它们将自动清除。

答案 2 :(得分:0)

您需要一些东西来存储这些对象。例如,您可以使用std::vectorstd::map。您可以在这些数据结构中存储无限数量的对象(实际上您受到内存量的限制,让我们说几乎无限制),而不需要关心内存,因为它是自动管理的。

答案 3 :(得分:0)

编辑:好的,这不是答案。 OP希望在运行时任意对象计数! 这个问题可能是模板元编程。

使用向量存储指针,使用宏定义新指针并将其推送到向量。 在结束之前,使用向量来释放。

#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;

}