【问题标题】:How to create an array of objects with parameterized constructor如何使用参数化构造函数创建对象数组
【发布时间】:2017-01-13 12:17:29
【问题描述】:

我需要使用非默认构造函数创建一个对象数组。应该应用什么语言特性来实现这一点?

这行代码不允许我这样做。

Object objects[10]{("foo", "bar")};

【问题讨论】:

标签: c++


【解决方案1】:

除非你想在初始化列表中指定所有单独的对象,否则使用简单的数组是不可能的。

但是,std::vector 非常简单,因为 constructor overload 采用向量的大小将所有元素初始化为的对象。所以你可以做类似的事情

std::vector<Object> objects(10, Object("foo", "bar"));

上面将创建一个包含十个元素的向量,所有元素都初始化为Object("foo", "bar")的副本。

【讨论】:

  • 任何解释为什么这在低级编程方面不起作用?
  • @Tracy “低级编程”是什么意思?你想让它与普通数组一起工作吗?为什么?您要么适应使用该语言中可用的工具,要么适应解决您可能看到的缺陷(如显式初始化数组中的每个元素)。无论哪种方式,您都无法将语言锤炼成您想要的形式和形状,您必须适应。或者将语言更改为更适合您需求的语言(这只是您的另一种适应方式)。
  • 为什么?我想尽我所能理解所有这些东西。我喜欢低级编程。
  • @Tracy 传统上,“低级编程”意味着在准硬件上编写,如低级设备驱动程序或小型嵌入式系统。使用向量或数组实际上与 IMO 无关。此外,使用所谓的“低级编程”(假设使用普通数组和指针)通常会使您的程序更难维护并且更容易出错。虽然了解数组和指针的原理以及如何使用是件好事,但如果您使用标准库的全部功能,您作为 C++ 程序员的生活将会如此轻松得多。
  • 我认为要使此解决方案起作用,您还需要将元素类型的复制构造函数存储在向量中。对于某些对象,复制构造函数被有意删除。所以你可能不得不用 the_vector.emplace(the_vector.end(), args_for_constructor...) 来构造每个对象
【解决方案2】:

您可以在对象上使用向量或指针数组。

Object* arr[6];
for (int i = 0; i < 6; i++)
{
     arr[i] = new Object("angry dog", 6);
}

【讨论】:

    【解决方案3】:

    使用= 并将您的值传递给初始化列表中的非默认ctor。不过,这样你应该定义数组中的每个值。

    Example

    int main()
    {
        struct A {
            int _v;
    
            A(int v) : _v(v) {}
        };
    
        A my_a[3] = {0, 1, 2};
    
        for (auto i : my_a)
          std::cout << i._v << ", ";
        std::cout << "\n";
    
    }
    

    【讨论】:

      【解决方案4】:

      简短的回答是原始数组无法做到这一点。另一种方法是使用std::vector,它提供了这种可能性。

      【讨论】:

        【解决方案5】:

        这样的?

        #include <array>
        #include <iostream>
        
        struct foo {
            int a, b;
        };
        
        int main()
        {
          std::array<foo, 4>  v= {{ {1, 2}, {2, 3}, {3, 4}, {4, 5} }};
          for (auto f : v) {
              std::cout << f.a << ' ' << f.b << std::endl;
          }
        }
        

        【讨论】:

          【解决方案6】:

          Using Double pointer(指针指向指针的概念):指向指针的指针是多重间接的一种形式,或者说是一个指针链。通常,指针包含变量的地址。当我们定义一个指向指针的指针时,第一个指针包含第二个指针的地址,它指向包含实际值的位置,如下所示。 在这里我们可以分配一些要分配的块,因此对于每个索引,我们必须使用 new 关键字调用参数化构造函数来初始化

          #include <iostream> 
          #include <string>
          #define N 5 
            
          using namespace std; 
            
          class Test { 
              // private variables 
              string x, y; 
            
          public: 
              // parameterised constructor 
              Test(string x, string y) 
              { 
                  this->x = x; 
                  this->y = y; 
              } 
            
              // function to print 
              void print() 
              { 
                  cout << x << " " << y << endl; 
              } 
          }; 
            
          int main() 
          { 
              // allocating array using 
              // pointer to pointer concept 
              Test** arr = new Test*[N]; 
            
              // calling constructor for each index 
              // of array using new keyword 
              for (int i = 0; i < N; i++) { 
                  arr[i] = new Test(to_string(i), to_string(i + 1)); 
              } 
            
              // printing contents of array 
              for (int i = 0; i < N; i++) { 
                  arr[i]->print(); 
              } 
            
              return 0; 
          } 
          

          【讨论】:

            【解决方案7】:

            C++ 中的数组可以有不同的含义。 array 用于在 C++11 中添加的固定大小的数组、对象的原始数组 T[](与 T* 相同)或向量。

            1. array = { } 可以显式初始化每个对象,比如大括号内的string("ad")。
            2. T* 或 T[] 你不能这样做,唯一的方法是使用默认构造函数进行初始化。
            3. T** 或 T*[],你可以用 T 的任何参数化构造函数进行初始化
            4. vector 您可以使用 emplace(v.end(), args...) [可选在循环中] 来初始化相同或可变参数。这可能比 3 更有效,因为 3 中的对象可能分散在不同的内存位置。

            以上列表可能不完整,可能存在错误。意在开启这个思路,欢迎大家指正和改进。

            【讨论】:

              【解决方案8】:

              多年后,我遇到了同样的问题。 我正在使用这个简单的结构:

              class test{
                const char *x;
              public:
                test(const char *a): x(a) {} //no default constructor
              };
              
              //workaround for static initializer
              template <typename T> class obj_init: public T{
              public:
                obj_init(): T("foo") {} //parameters
              };
              
              //static array
              obj_init<test> list[10];
              

              问候, 加布里埃尔

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2013-10-30
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2016-07-05
                • 1970-01-01
                相关资源
                最近更新 更多