【问题标题】:how to dynamically declare an array of objects with a constructor in c++如何在 C++ 中使用构造函数动态声明对象数组
【发布时间】:2011-12-11 09:04:45
【问题描述】:

我想知道当对象需要为构造函数传递的东西时,是否可以创建一个对象数组。我想要这样的东西:

MyClass *myVar;
myVar = new MyClass[num];  // I would like to specify the array size after declaration
int i = 0;
for(i = 0;i < num;i++)
   myVar[i] = new MyClass(0,0);  // I would also like to populate the array with new objects

我知道这行得通:

MyClass *myVar;
myVar = new MyClass[num];

但这仅在构造函数没有传递任何内容时才有效。我正在尝试做的事情可能吗?如果是这样,我该怎么做?

编辑:我发现了如何使用数组来做到这一点。这是我的做法:

MyClass **myVar;
myVar = new MyClass *[num];
for(i = 0;i < num;i++)
   myVar[0] = new MyClass(0,0);

我会使用向量等,但我的老师告诉我们尽可能使用基本数组。我实际上是从老师编写的一些代码中得到的上述解决方案。谢谢大家的帮助!

【问题讨论】:

  • 迟到的评论,但对于遇到此问题的任何人,我认为应该是 myVar[i] = new myClass(0, 0) 而不是 myVar[0]

标签: c++


【解决方案1】:
MyClass *myVar;
myVar = new MyClass[num];

实际上,在这种形式下,您不能调用带有参数的构造函数。语言规范不允许这样做。

但是,如果您使用我推荐您使用的std::vector,那么您可以创建一个调用非默认构造函数的向量:

#include <vector> //header file where std::vector is defined

std::vector<MyClass>  arr(num, MyClass(10,20));

它创建一个包含num 元素的向量,每个元素都是通过调用类的复制构造函数创建的,并将MyClass(10,20) 作为参数传递给它。

向量也很好,因为现在您不需要自己管理内存。既不是手动分配,也不是手动释放。另外,您可以随时致电arr.size() 了解元素的数量。你总是知道向量包含多少元素。您也可以随时添加元素,只需调用.push_back()成员函数:

arr.push_back(MyClass(20,30)); 

现在您可以访问元素,就像访问数组一样,即使用索引:

f(arr[i]); // 0 <= i < arr.size();

此外,您可以使用有助于惯用编程的迭代器,使您能够使用来自&lt;algorithm&gt; 标头的各种算法函数:

#include <algorithm> //header file where std::for_each is defined

std::for_each(arr.begin(), arr.end(), f);

其中f 是一个函数,它采用MyClass&amp;(或MyClass const &amp;)类型的一个参数,具体取决于您想在f 中执行的操作。

在 C++11 中,您可以将 lambda 用作:

std::for_each(arr.begin(), arr.end(), [](const MyClass & m)
                                      {
                                           //working with m 
                                      });

【讨论】:

  • 感谢您的帮助!我实际上是在寻找一种使用数组而不是向量的方法,因为我的老师希望班级使用数组来代替。不过我找到了答案。
  • @user972276:对于数组,如果您想调用非默认构造函数,您的第一种方法是可以做的。但是,将来,如果您需要数组,首先考虑使用std::vector。这是一个很棒的容器,有很多很酷的功能。
【解决方案2】:

在C++0x中,这个语法有效,可以在new表达式中调用非默认构造函数:

MyClass *myVar;
myVar = new MyClass[2]{{10, 20},{20, 30}};

但我怀疑当元素数量仅在运行时可用时它是否有效。

向量方法会更好,如 Nawaz 的回答所示。

【讨论】:

    【解决方案3】:

    指向指针的指针等价于 1. 指针数组和 2.vector 指针向量。我过去这样做的一种方法是使用双指针。这种方法消除了向量数据结构的开销,并且需要优先的内存效率。

    MyClass ** myvar;
    myvar = new Myclass*[num]
    for(int i = 0; i < num; i++){
    *(myvar+i) = new Myclass(i);}
    

    适用于您可以想象的几乎任何控制结构。缺点是内存分配不连续,影响大量num的速度。

    【讨论】:

    • 这类似于vector 方法,只是你自己管理细节。如果您不想要矢量的开销成本,这似乎是最好的解决方案。
    【解决方案4】:

    你也可以这样做:

    MyClass *myVar[num];
    
    for(int i = 0; i < num; i += 1)
    {
        myVar[i] = new MyClass(0, 0);
    }
    

    【讨论】:

      【解决方案5】:

      其实你可以使用placement new来处理这个问题:

      MyClass * myVar;
      myVar = reinterpret_cast<MyClass *>(new char[num * sizeof(MyClass)]);
      int i = 0;
      for (i = 0; i < num; i++) {
          new(&myVar[i]) MyClass(0,0);
      }
      

      【讨论】:

      • 你应该使用std::aligned_storage而不是new char[]
      • 另外应该提到的是,要释放这个内存,你必须循环调用每个对象的析构函数,然后调用delete[] reinterpret_cast&lt;char *&gt;(myVar);
      【解决方案6】:

      @Nawaz 的回答非常适合使用向量,但对我不起作用,因为它创建了相同对象的向量(它们都引用同一个对象)

      class Graph
      {
       public:
        Graph(long V); // none default Constructor
      }
      std::vector<Graph>  myGraph;
      for (int i = 0; i < T; i++) // read all graphs
          {
              Graph newGraph(N);
              myGraph.push_back(newGraph);
          }
      

      【讨论】:

        猜你喜欢
        • 2020-06-26
        • 1970-01-01
        • 2020-06-01
        • 1970-01-01
        • 1970-01-01
        • 2019-04-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多