繁体   English   中英

我如何使用“new”语句初始化一个包含 2 个对象的数组,并将第一个元素的指针指向 map?

[英]How can i initialize an array of 2 objects with the "new" statement, and put the pointer of the first element to a map?

请注意,我是上课的新手。 这是我想要的想法(并且需要使我的代码更干净和通用)

在我的 function StartupRoutine(std::map<std::string, MyClass*>& mymap)中:

MyClass myobj[2];
myobj[0] = new MyClass(/* constructor parameters */);
myobj[1] = new MyClass(/* constructor parameters */);

/* do some stuff and call some setters */

mymap.insert(std::pair<std::string, MyClass*>("something", myobj)); /* myobj should be equal to &myobj[0] right? */

我是从main调用它的。 我希望这些课程一直保留到我调用delete为止。

我想这样做是为了轻松访问 class 方法,这两个对象的偏移量如下: mymap["something"] and mymap["something"]+1

我想对单个对象使用相同的map ,对 2 或 4 个对象使用 arrays,出于多种原因,

我已经尝试了很多很多方法并谷歌了几个小时。 我试过类似上面例子的东西。 然后我尝试将myobj初始化为单个指针:

MyClass* myobj;
myobj = new MyClass(/* constructor parameters */);
myobj+1 = new MyClass(/* constructor parameters */);

我很确定这真的是错误的,因为我正在尝试访问一个我不应该访问的 memory 地址。

编辑:感谢大家的帮助,我将在这里回答评论:关于new声明,你们是对的,我是个白痴,经过数小时的尝试后忘记了。 这里是我正在做的更详细的解释:我正在用 SDL 制作一个简单的游戏,我有我的 class 纹理。 我想要 map 我的纹理(可能有更好的方法来处理它们,但这是我想出的最好的解决方案,可以使我的代码更加通用(并且更好看))。 所以大多数纹理都在 map 中,将是单个 object,但在某些情况下,对于动画,我使用无缝纹理并且我需要相同图像但具有不同坐标的更多实例(它们都是类的属性). 我想将普通纹理作为单个对象处理,将无缝纹理作为 arrays 中的 2 或 4 个对象处理在同一个 map 中。我知道我可以像map["water1"]map["water2"]一样简单地将它们分别处理 map 但是我这非常非常难看,我正在努力寻找更好的解决方案。

顺便说一句,我做这一切都是出于教育目的。 PS:抱歉我缺席,但周末我会工作。

第二次编辑:如果我使用 malloc 而不是 new 并执行此操作怎么办:

MyClass* MyObj = (MyClass*)malloc(sizeof(MyClass)*2);
*MyObj = MyClass(/* constructor parameters */);
*(MyObj+1) = MyClass(/* constructor parameters */);
mymap.insert(std::pair<std::string, MyClass*>("something", MyObj));

出于某种原因,当我尝试调用 class 方法时它崩溃了,例如:

mymap["something"]->MyMethod();

您的方法的直接问题是您试图将 MyClass* 值存储在 MyClass 数组中。 new语句返回一个指针,而不是直接的 object 引用。 您可以使用以下其中一项:

使用指针数组。

通过添加额外的 memory 访问层,您几乎可以按照当前尝试的方式来完成此操作。

MyClass* myobj[2];
myobj[0] = new MyClass(...);
myobj[1] = new MyClass(...);

/* ... */

mymap.insert(std::pair<std::string, MyClass**>("something", myobj));

要获取指向数组中第 i 个元素的指针,可以使用mymap["something"] + i

但是,这样做很麻烦,如果您经常与双指针交互,可能会导致很多麻烦和段错误。 我会推荐后一种方法。

使用矢量

包含 header <vector>以使用标准库向量。 向量是动态长度的数据结构,具有内置范围检查等方便的功能。 您可以new一个向量,使其在 function scope 结束后仍然存在,只需确保在完成后将其delete (并在删除放入其中的 MyClass* 值后)。

std::vector<MyClass*>* myobj = new std::vector<MyClass>();
myobj->push_back(new MyClass(...));
myobj->push_back(new MyClass(...));

/* ... */

mymap.insert(std::pair<std::string, std::vector<MyClass*>* >("something", myobj));

然后,您使用mymap["something"]->at(i)访问向量中的第 i 个元素,它是指向 MyClass object 的指针。

既然你说你会使用不同大小的 collections ,这可能会为你省去很多麻烦。 任何时候你试图访问向量范围之外的元素,它都会抛出错误。 如果您使用数组和mymap["something"] + i犯了同样的错误,它只会抓取 memory 中位于该数组旁边的任何垃圾 memory 并且不知道区别。

除非您有某些特定原因不这样做,否则我强烈建议您使用向量而不是数组和 memory 算术。

MyClass myobj[2];

定义两个MyClass实例的数组。 不是指向实例的指针,所以使用

myobj[0] = new MyClass(/* constructor parameters */);

不可能。 new提供指向动态分配的MyClass指针,而指向MyClass指针不是Myclass 您不能分配它们。 另外,这里有两个MyClass es:assignee 和由new分配的全新的 es,并且最终必须有人用delete返回new ed 以防止泄漏。

当您定义一个数组时,它会立即构造数组中的每个元素。 如果元素没有默认构造函数(没有参数或只有默认参数的构造函数),则数组只能用list定义。

假设我们有一些简单的东西

class MyClass
{
public:
    MyClass(int ,int);
};

这需要两个整数。 我们可以为这些整数提供一个列表

MyClass myobj[2] = {
    {1, 2},
    {3, 4}
};

我们可以使用列表中的现有变量

MyClass myobj[2] = {
    {a, b},
    {c, d}
};

我们也可以从 function 获得它们

MyClass myobj[2] = {
    {get_int(), get_int()},
    {get_int(), get_int()}
};

我可能在这里遗漏了一些其他偷偷摸摸的技巧,但你可能不需要它们来完成这项工作。

现在你可以

mymap.insert(std::pair<std::string, MyClass*>("something", myobj));

但是您必须绝对确定myobjmymap长。 不要做类似的事情

void function_of_doom(map<<std::string, MyClass*>> & mymap)
{
    MyClass myobj[2] = {
        {a, b},
        {c, d}
    };
    mymap.insert(std::pair<std::string, MyClass*>("something", myobj));
}

其中myobj将在mymap之前从 scope 中取出 go。

边注:

不要尝试类似的东西

myobj[0] = *new MyClass(/* constructor parameters */);

即使编译器允许它。 new MyClass(/* constructor parameters */)创建了一个全新的、动态分配的MyClass浮动在存储的某个地方,并提供了一个指向它的指针,以便您可以找到它。 *取消引用指针,得到指向的 object,而myobj[0] =将新的 object 复制到myobj[0]中。 所有这些都是完全合法的,看起来你得到了你想要的。 但是您丢失了指向新 object 的指针,如果没有指针,您将不知道它在哪里,因此很难找到它,因此您可以使用delete返回 memory。 如果要动态分配 object,则始终需要保留对 object 的引用,以便在完成后释放它。 一旦程序变大,这比看起来更难,所以一般的经验法则是极少使用new

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2023 STACKOOM.COM