【问题标题】:Setting Ctor params when dynamically allocating an array动态分配数组时设置 Tor 参数
【发布时间】:2015-06-10 05:57:34
【问题描述】:

我正在尝试动态分配对象数组。我的每一件物品 在他们的构造函数中有一个必须初始化的参数。我宁愿在施工时初始化它们,因为我认为这会节省时间。如何在分配时使用需要参数的构造函数初始化动态分配的对象数组?

class Thingy{
private:
    int* a;
public:
    Thingy(int size);
};

class ThingyLayer{
private:
    Thingy* m_things;
public:
    ThingyLayer(int n){
        m_things = new Thingy[n]; //!< How do I pass a param here to the ctor of Thingy
    }
};

在这种情况下,我不想使用std::vector,因为有一天我可能想在不支持 STL 的嵌入式系统上运行它,比如 Atmel AVR 芯片。所以我正在寻找如何使用指针来做到这一点。

我已经尝试过了,m_things = new Thingy[n](val),但这不起作用,因为它会引发编译器警告。我还查看了Dynamically allocating an array of objects,但这并没有回答我的问题。

【问题讨论】:

  • 所有元素的参数相同?
  • @Christophe 所有参数都相同。
  • 语言中存在一个特性并不意味着它应该被使用。 new 的数组形式就是其中之一。
  • 显然,AVR 有std::vector,对于 16k 芯片来说足够小:andybrown.me.uk/wk/2011/01/15/…(未选中,我从未使用过)。
  • 您可以重载 operator new[] 以允许传递参数,或使用参数的默认值。见drdobbs.com/cpp/calling-constructors-with-placement-new/…

标签: c++ arrays


【解决方案1】:

执行此操作的 C++ 方法是 std::vector我不相信你真的有充分的理由使用指针来代替好吧,你说出了一个原因,我真的不能判断好不好用,因为我对嵌入式系统一窍不通):

class ThingyLayer{
private:
    std::vector<Thingy> m_things;
public:
    ThingyLayer(int n) : m_things(n,val){}
};

这也使您免于手动newing 和deleteing 东西的痛苦,正确地做这不是一件有趣的事情。

std::vector 还带有一大堆其他简洁的功能,如果您不熟悉,请查看我链接的手册页。

【讨论】:

    【解决方案2】:

    您可能可以通过以下方式获得:

    ThingyLayer(int n){
        char* temp = new char[sizeof(Thingy)*n];
        for (int i = 0; i < n; ++i )
        {
            // Use placement new to construct Thingy objects.
            new (temp+i*sizeof(Thingy)) Thingy(10); // Assuming 10 here.
        }
        m_things = reinterpret_cast<Thingy*>(temp);
    }
    

    我有点犹豫,因为Thingychar 的对齐要求不同。我不确定这会如何影响代码的行为。

    如果你走这条路,ThingyLayer 的析构函数也必须精心设计。

    class ThingyLayer
    {
       private:
          int m_n;
          Thingy* m_things;
       public:
          ThingyLayer(int n) : m_n(n) {
             char* temp = new char[sizeof(Thingy)*n];
             for (int i = 0; i < n; ++i )
             {
                // Use placement new to construct Thingy objects.
                new (temp+i*sizeof(Thingy)) Thingy(10); // Assuming 10 here.
             }
             m_things = reinterpret_cast<Thingy*>(temp);
          }
    
          ~ThingyLayer()
          {
             for (int i = 0; i < m_n; ++i )
             {
                // Call the destructor of Thingy explicitly.
                m_things[i].~Thingy();
             }
    
             // Now deallocate the memory using a char*.
             char* temp = reinterpret_cast<char*>(m_things);
             delete [] temp;
          }
    
          // Make sure to implement copy constructor and copy assignment 
          // operator properly. If you use the default copy constructor and
          // copy assignment operator, the program will exhibit undefined
          // behavior.
    
          ThingyLayer(ThingyLayer const& copy) { ... }
          ThingyLayer& operator=(ThingyLayer const& rhs) { ... }
    
    };
    

    延伸阅读:What is The Rule of Three?

    【讨论】:

    • 如果您遵循此路径,您还必须手动删除对象,然后在转换为 delete [] 后将 delete []... 我不太推荐这个。
    • 清理代码是什么?清理时是否需要多次强制转换?
    • 如果你不能使用vector,那么下一个最好的事情就是自己实现vector,这(基本上)就是vector的作用。但不要忘记rule of three/five
    • 我在m_things[i]::~Thingy(); 上遇到编译器错误,编译器说它在:: 之前预期;。这是什么意思?
    • @HSchmale:这意味着这个家伙发明了语法。他的意思是m_things[i].~Thingy();他还忘记了复制构造函数和赋值运算符,使得这个类非常破碎。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-14
    • 2020-03-06
    • 1970-01-01
    • 2023-01-10
    • 2020-09-13
    • 2015-03-09
    • 2012-05-01
    相关资源
    最近更新 更多