c ++ struct,如何动态创建struct对象,

时间:2015-03-19 13:25:12

标签: c++ struct

我有这样的结构:

struct MYSTRUCT {
    ....
};

如果我用这样的for循环创建struct对象:

for(int i = 0; i < 2; i++){
    MYSTRUCT *mystruct;
}
由于名称相同,

mystruct每次都会相同吗?上面的代码与此代码之间有什么区别:

MYSTRUCT *mystruct0;
MYSTRUCT *mystruct1; 

如何以更简单的方式创建不同的struct对象?

MYSTRUCT *mystruct0;
MYSTRUCT *mystruct1;
...
MYSTRUCT *mystruct99;
MYSTRUCT *mystruct100; 

如果我按照下面的方式进行操作,所有结构指针是否相同或彼此隔离?

vector<MYSTRUCT *> mystructs;
for(int i = 0; i < 100; i++){
    MYSTRUCT *mystruct;
    mystructs.push_back();
}

5 个答案:

答案 0 :(得分:2)

首先,您永远不应该尝试生成变量名称。 它不是这样做的方式。

你应该使用一个容器(就像你的例子中的一个std::vector),这正是你想要的东西:放置其他几个相同类型的东西。

在你的例子中:

struct MyStruct {  // Don't name your struct in all caps.
                   // it's generally reserved for MACROS. Use CamelCase
    // blablabla

}

除非您需要,否则不要使用指针,通常使用值更容易更高效。如果你需要将向量的一个元素传递给一个函数,那么这个函数可以修改它,你可以将一个迭代器传递给那个元素。

vector<MyStruct> mystructs;
for(int i = 0; i < 100; i++){
    mystructs.emplace_back(MyStruct{});
}

此外,如果您的结构中包含需要初始化的字段,您可能需要使用初始化列表或定义构造函数。

如果您需要使用动态分配,您可以执行以下操作:

vector<MyStruct*> mystructs;
for(int i = 0; i < 100; i++){
    mystructs.emplace_back(new MyStruct{});
}

现在,向量包含指针,而不是对象。每个对象都在他自己的记忆位置中单独分配,因此没有保证他们彼此相邻。 这对性能非常重要:指针为您提供间接性。 间接导致痛苦。痛苦导致愤怒...... blablabla =&gt;欢迎来到黑暗面。

答案 1 :(得分:1)

在您的示例代码中:

for(int i = 0; i < 2; i++){
    MYSTRUCT *mystruct;
}

您根本不会创建对象。您所做的只是声明指向MYSTRUCT的指针。这些指针未初始化,因此不指向任何事物(尚未)。此外,指针(mystruct)本身在堆栈上分配,其生命周期限制在for循环的范围内。

我不确定您要实现的目标,但如果您需要多个MYSTRUCT类型的对象,则不应尝试在这样的循环中创建它们。相反,声明一个数组或std::vector并适当初始化。我会留给你弄清楚如何做到这一点。当你这样做时,要注意静态和动态数组之间的区别,以及它们对内存管理的影响!

修改 根据要求,我会详细说明您提供的最终摘要:

vector<MYSTRUCT *> mystructs;
for(int i = 0; i < 100; i++){
    MYSTRUCT *mystruct;
    mystructs.push_back();
}

这里发生的是你声明一个指向MYSTRUCT的空指针。到现在为止还挺好。现在,判断正文,你想用指向实际对象的指针填充这个向量,但这不会发生在你的代码中。鉴于push_back需要MYSTRUCT*作为参数,我怀疑这甚至会编译。因此,要执行您打算执行的操作,您的代码应该在每次迭代中执行:

  1. 在堆上分配对象
  2. 将指向此对象的指针推到矢量背面。
  3. 这将如下所示:

    vector<MYSTRUCT*> vec;
    for (int i = 0; i != n; ++i) // pre-incr is good practice!
        vec.push_back(new MYSTRUCT); // optionally add constructor arguments 
    

    但是,这会向您介绍新的职责:您是使用new明确请求内存的人,因此您应该使用delete显式释放内存。除非MYSTRUCT是多态的(包含虚拟成员),否则你可以很容易地绕过这个(即使它多态的,你不应该这样做,但这是另一个话题)。

    这个问题的答案是:不要存储指针,存储对象:

    vector<MYSTRUCT> vec; // no pointer!
    for (int i = 0; i < 100; ++i)
        vec.push_back(MYSTRUCT()); // create an unnamed instance and copy to the back of the vec
    

    在那里,您刚刚创建了n MYSTRUCT实例的向量。没有指针,没有newdelete,简单易行!

答案 2 :(得分:1)

struct是您定义的数据类型,当您MYSTRUCT *mystructMYSTRUCT对象声明指针并且指针被调用时mystruct 1}}与int *pointer_to_int的使用情况相同。

对于第一个版本,您在每次迭代时重新声明mystruct,而第二个版本声明两个独立变量。如果您想轻松声明一组MYSTRUCT*,请使用MYSTRUCT*MYSTRUCT* mystruct_pointers_array[100]数组。

注意 MYSTRUCT*指针与MYSTRUCT变量不同,您需要取消引用指向访问MYSTRUCT元素的指针。例如。 mystruct->x

答案 3 :(得分:0)

为此目的使用std :: vector:

std::vector<MYSTRUCT *> v(100);
for (auto& pointer : v)
   pointer = new MYSTRUCT(/*...*/); //initializating (writing address to pointer)

以您的方式初始化指针类型的对象。换句话说,您只为指针分配内存,您必须在其中为您的结构写入地址或 nullptr -value。

答案 4 :(得分:0)

其他人也说过类似的事情,但具体来说我会这样做:

std::vector <MYSTRUCT *> vect;
for(int i = 0; i < 2; i++){
    vect.push_back();
}

然后你可以像数组一样访问每个元素,比如vect[0]。加上std::vector,您可以使用vect.front()访问第一个元素(元素0),使用vect.back()访问最后一个元素。

虽然如果没有分配已单独初始化的MYSTRUCT,它就没用了,但我可以看到struct *向量的用处。