2010-08-12 118 views
6

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

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; } 
}; 

谢谢,博大Cydo。

+6

我知道这只是一个示例代码,但是正如所写的那样,类存在严重的内存管理问题(默认拷贝文件将允许多次释放内存)。使用RAII,使用智能指针或容器。有了适当的RAII,你可能会发现你根本不需要使用自己的删除方法 – 2010-08-12 09:43:06

+8

@jk:借调,我更喜欢'std :: vector '。 – fredoverflow 2010-08-12 09:44:33

回答

3

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

所以:

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

此外,作用域数组不能被复制 - 让你避免在另一个答复中提到讨厌的拷贝构造函数释放问题。

+0

其实,你应该使用'boost :: scoped_array'。 – 2010-08-12 11:39:31

+0

谢谢。刚刚发现它是一个数组alloc。教我正确地阅读这个问题。 – 2010-08-12 11:40:21

+1

'delete'是一种代码味道:它应该只出现在专用的资源管理类中......并且这些通常已经在可用的库中正确编码(例如STL/Boost)。 – 2010-08-12 14:18:36

-1

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

+12

其实不然。 (在这两种情况下,如果内存分配失败,这个构造函数就无法做到这一点,所以不应该捕获这个异常,并且可以使用函数try块来获取try-catch块中的所有内容) – GManNickG 2010-08-12 09:43:10

1

我会说两者在它们产生的效果上都是相等的,都是“正确的方式”。 我更喜欢初始值设定项列表,但为了能够在尝试分配内存之前测试无效长度参数,我会选择第二个变量。

+1

它们对于简单类型是等同的,但通常它们不是。使用初始化列表将从参数构造对象;使用构造函数主体将默认构建对象,然后重新分配它。这可能效率较低,并且只有在对象是默认可构建和可分配的情况下才有效。 – 2010-08-12 17:16:47

2

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

0

memory成员变量的指针,如果你在初始化列表分配它,它失败了,你的类没有初始化,你不需要稍后释放它(由于所使用的C RAII设计模式++用于类初始化)。如果你在构造函数体内分配它的内存,会发生类似的行为。

但是,如果你想处理的东西,然后分配它的内存在构造函数的正文。检查某个东西或尝试/捕获它或打印一些有用的消息,但至少必须抛出另一个异常,因为您的类初始化已被破坏。

我认为memory在构造函数体内的分配比另一个更具可读性。

相关问题