是类构造器具有未定义的行为

Is class contructor has undefined behaviour

本文关键字:未定义 构造器      更新时间:2023-10-16

我的下一个类有未定义的行为?我认为它定义得很好,因为我正在通过引用传递构造函数参数。我说的对吗?

class C
{
  int* elem;
  public:
    C(int s[]) :elem(s){}; // Array arguments passed by reference, so its well defined?
    void Print()
    {
      cout << elem[1] << endl;
    }
    ~C()
    {
       delete[] elem; 
    }
};
int main()
{
    C x(new int[2]{1,3});
    return 0;
}

代码中没有未定义的行为。此外,您不是通过引用传递,而是按值传递指针。

它是明确定义的;你正在创建一个数组,将一个有效的指针传递给构造函数(构造函数需要一个指针,尽管它看起来好像需要一个数组),存储该指针,然后通过它访问一个有效的数组元素。

唯一的问题是内存泄漏 - 您永远不会删除数组。

更新 现在你已经添加了一个析构函数来删除数组,这个类是非常危险的 - 如果你复制它,那么两个副本都会尝试删除同一个数组。这将导致未定义的行为。您需要根据三法则防止复制或正确实施复制。如果指针不是指向使用 new[] 创建的数组,您还将获得未定义的行为。

一旦你学会了如何手动管理资源,以及正确处理所有细节是多么困难,你通常会使用库类来为你做这件事。在这种情况下,std::vector<int>将是理想的。这样做有时被称为"零规则"(如注释中所述),因为它完全不需要编写自己的析构函数或复制/移动语义 - 它们都来自您正在使用的类,有人已经正确实现了。