我知道这是一个非常古老的辩论,已经在世界各地进行了很多次讨论。但是我目前在决定在特定情况下在静态数组和动态数组之间使用哪种方法而不是另一种方法时遇到了麻烦。实际上,我不会使用C++ 11,而是会使用静态数组。但是我现在很困惑,因为两者可能都有同等的好处。
第一个解决方案:
template<size_t N>
class Foo
{
private:
int array[N];
public:
// Some functions
}
第二种解决方案:
template<size_t N>
class Foo
{
private:
int* array;
public:
// Some functions
}
我无法选择,因为两者都有各自的优势:
我认为没有一个好的解决方案,但是我想征求一些意见,或者只是想知道您对这一切的看法。
最佳答案
我实际上会不同意“取决于”。永远不要使用选项2。如果要使用转换时间常量,请始终使用选项1或std::array。您列出的一个优点是,动态数组在分配之前不承担任何责任,实际上是一个可怕的,巨大的缺点,需要特别指出。
永远不要包含具有多个构造阶段的对象。永远不能。那应该是通过一些大纹身来内存的规则。只是永远不要做。
当您的僵尸对象还不太活跃,尽管它们也都还没死时,管理其生命周期的复杂性就会成倍增加。您必须检查每种方法是否完全有效,或者仅假装还可以。异常安全性要求析构函数中有特殊情况。现在,您已经添加了必须在N个不同位置检查的要求(#方法+ dtor),而不是简单的构造和自动销毁。而且编译器不在乎是否检查。其他工程师不会广播此要求,因此他们可能以不安全的方式调整您的代码,使用变量而不进行检查。现在,所有这些方法都具有多种行为,具体取决于对象的状态,因此对象的每个用户都需要知道预期的结果。 僵尸会破坏您的(编码)生活。
相反,如果程序中有两个不同的自然生命周期,请使用两个不同的对象。但这意味着您的程序中有两个不同的状态,因此您应该有一个状态机,其中一个状态只有一个对象,而另一个状态则只有两个对象,并由异步事件隔开。如果两点之间没有异步事件,如果它们都适合一个功能范围,则分离是人为的,您应该进行单相构造。
转换时间大小应转换为动态分配的唯一情况是当该大小对于堆栈而言太大时。然后进行内存优化,应始终使用内存和性能分析工具对其进行评估,以了解最佳方法。选项2永远不会是最好的(它使用裸露的指针-因此我们再次失去了RAII以及任何自动清理和管理功能,添加了不变量,并使代码更复杂且容易被其他人破坏)。尽管您可能不喜欢按时间分配堆开销,但最好使用Vector(由bitmask建议)来进行适当的考虑。其他选项可能是应用程序镜像中的静态空间。但同样,只有在确定存在内存限制后才应考虑这些因素,并且从那里开始的操作应由实际的可衡量需求确定。