1

我想创建一个数据向量,但我想设置它的大小并在子函数中填充它的元素。现在是使用 new 运算符的合适时机吗?有更好的方法吗?这似乎是一个合适的时间,但我犹豫不决,因为为什么 C++ 程序员应该尽量减少“新”的使用?

int main()
{
    vector<double> *array1;
    vector<double> *array2;
    OtherArgs otherArgs;
    FillArrays(array1,array2,otherArgs);
    //Do other stuff 
    delete array1;
    delete array2;
}

void FillArrays(vector<double> *&array1, vector<double> *&array2, OtherArgs &otherArgs)
{
    int size=GetSize(otherArgs);
    array1 = new vector<double>(size);
    array2 = new vector<double>(size);
    //Other code to fill the arrays
}

谢谢

4

2 回答 2

7

以下是原始样本麻烦的几个原因

  • 代码在遇到异常时会泄漏内存,因为delete调用不受保护
  • 如果FillArrays传递一个非 NULLvectory<double>值,它将泄漏内存,因为它没有删除以前的值。delete即使它想 调用它也不能可靠地调用,因为该值可能已被堆栈分配。

最简单的方法是在堆栈上声明值并以这种方式通过引用传递它们。

int main()
{
    vector<double> array1;
    vector<double> array2;
    OtherArgs otherArgs;
    FillArrays(array1,array2,otherArgs);
    //Do other stuff 
}

void FillArrays(vector<double> &array1, vector<double> &array2, OtherArgs &otherArgs)
{
    int size=GetSize(otherArgs);
    //Other code to fill the arrays
}

vector<T>以这种方式声明时,它们会将自己初始化为一个空列表。然后,该FillArrays方法可以根据需要填充它们。

于 2012-05-30T18:53:20.253 回答
3

不,这是对new.

如果您必须使用newand delete1,请将它们用作书挡。删除表达式应与新表达式处于逻辑一致的上下文中。

因此,如果您new在 c-tor 中,则应该delete在 d-tor 中。如果你new在一个分配函数中,你应该delete在一个释放函数中。这两个调用的排列方式应该使得一个开始一个操作,另一个完成它。

这意味着对new和的调用delete应该存在于功能或对象层次结构的同一层中。具体来说,new应该delete被视为实现细节,而不是 API 合同的一部分。2

在您的情况下, new 和 delete 处于完全不同的上下文中。new在实现内部,而delete在客户端中调用。这导致编程错误。

除此之外,您的代码的非新版本(在 中创建空向量main,并通过引用传递它们)比该new版本更简单、更易于阅读且对异常更友好。

不,这不是什么时候使用的好例子new。然而,这是一个很好的例子,说明何时这样做。


1 您几乎不需要使用newand delete。如果您需要动态分配,只需让容器保留对象的副本。

2std::shared_ptr等人违反了这条规则—— newanddelete是合同的具体部分。这可能没问题,因为指针操作是它们存在的原因。但是 SO 已经看到了关于将非new指针存储在shared_ptr.

于 2012-05-30T19:00:16.253 回答