【问题标题】:What is the right way to allocate memory in the C++ constructor?在 C++ 构造函数中分配内存的正确方法是什么?
【发布时间】:2011-03-28 20:03:04
【问题描述】:

这是在 C++ 构造函数中通过new 分配内存的正确方法。参数列表中的第一种方式:

class Boda {
    int *memory;
    public:
        Boda(int length) : memory(new int [length]) {}
        ~Boda() { delete [] memory; }
};

或在构造函数中:

class Boda {
    int *memory;
    public:
        Boda(int length) {
            memory = new int [length];
        }
        ~Boda() { delete [] memory; }
};

谢谢,博达·赛多。

【问题讨论】:

  • 我知道这只是示例代码,但正如所写的那样,该类存在严重的内存管理问题(默认复制 ctor 将允许多次释放内存)。使用 RAII,使用智能指针或容器。使用适当的 RAII,您可能会发现根本不需要删除自己
  • @jk:借调,我更喜欢std::vector<int>

标签: c++ memory constructor new-operator


【解决方案1】:

如果您想捕获内存分配错误(您可能应该这样做),那么您必须在构造函数的主体中调用 new。

【讨论】:

  • 实际上不是这样。 (在这两种情况下。如果内存分配失败,这个构造函数就不能做任何事情,所以应该 not 捕获异常。你可以使用函数 try 块来获取整个事情一个 try-catch 块。)
【解决方案2】:

我想说两者在产生的效果上是相同的,而且都是“正确的方式”。 我更喜欢初始化列表,但我会使用第二个变体,只是为了能够在尝试分配内存之前测试无效的长度参数。

【讨论】:

  • 它们对于简单类型是等价的,但通常它们不是。使用初始化列表将从参数构造对象;使用构造函数主体将默认构造对象,然后重新分配它。这可能效率较低,并且仅在对象是默认可构造和可分配的情况下才有效。
【解决方案3】:

【讨论】:

  • +1 以获得常见问题解答的链接。应始终首先阅读或搜索常见问题解答。
【解决方案4】:

您应该使用可以为您处理它的资源管理类。否则,除了不必要地重复现有逻辑和维护复制/赋值运算符之外,您还会遇到一些严重的异常安全问题。

【讨论】:

  • 如果我需要最快的方法来管理分配的数组,如本例所示?我的项目中有完全相同的类(使用更多方法),并且禁止使用任何库。对于这个特定的实例,我需要(并且想要)自己管理内存。
【解决方案5】:

我认为最简单的方法是使用boost scoped array 并让其他人经过良好测试的库代码为您处理所有事情。

所以:

class Boda {
    boost::scoped_array<int> memory;
    public:
        Boda(int length) : memory(new int [length]) {}
       ~Boda() {}
};

此外,不能复制作用域数组 - 因此您可以避免另一个答案中提到的讨厌的复制构造函数释放问题。

【讨论】:

  • 其实你应该使用boost::scoped_array
  • 谢谢。刚刚发现它是一个数组分配。教我正确阅读问题。
  • delete 是一种代码味道:它应该只出现在专用的资源管理类中......而且这些通常已经在可用的库中正确编码(例如 STL / Boost)。
【解决方案6】:

memory 成员变量是一个指针,如果你在初始化列表中分配它并且它失败了,你的类没有被初始化,你以后不需要释放它(感谢RAII设计C++ 用于类初始化的模式)。如果你在构造函数的主体内分配它的内存,也会发生类似的行为。

但是如果你想处理一些东西,那么在构造函数的主体中分配它的内存。检查一些东西或尝试/捕捉它或打印一些有用的消息,但至少,你必须抛出另一个异常,因为你的类初始化被破坏了。

我认为构造函数主体中的memory 分配比其他分配更具可读性。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-30
    • 2021-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多