Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/145.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 返回前超出范围_C++ - Fatal编程技术网

C++ 返回前超出范围

C++ 返回前超出范围,c++,C++,下面的代码片段是我在VisualStudio中遇到的一个问题的简化版本 代码在运行期间进入析构函数 return temp; 调试单步执行 代码: classpoint2d { 公众: int x,y; }; 类poly2d { 公众: void运算符=(常量poly2d和temp) { 对于(cnt=0;cnt

下面的代码片段是我在VisualStudio中遇到的一个问题的简化版本

代码在运行期间进入析构函数

return temp;
调试单步执行

代码:

classpoint2d
{
公众:
int x,y;
};
类poly2d
{
公众:
void运算符=(常量poly2d和temp)
{
对于(cnt=0;cnt
我知道这篇文章毫无意义,但它被简化了,脱离了上下文,但同时也突出了我的问题。析构函数在return语句之前执行。然后是复制构造函数,然后是析构函数。它被删除了两次,显然会导致错误。这是我在6年多的修修补补中第一次遇到这个问题


谢谢。

您没有为类poly2d定义副本分配构造函数。在这种情况下,编译器将为您生成一个默认构造函数。这个构造函数所做的就是复制类的每个字段

这特别意味着,它复制指针点2d*p,而不是底层点

那么调用copy()时会发生什么呢

生成新的poly2d,即调用poly2d构造函数。这将生成一个新的点2D。现在,对copy()的调用已完成。实际指定给poly2d myPoly的是临时对象的副本。对copy()的函数调用一完成,就会调用temp对象的析构函数。此析构函数销毁临时对象指向的point2d对象。现在的问题是,在任何时候都没有为myPoly创建新的point2d对象。myPoly有一个指向temp指向的对象的指针,该对象现在已被删除。这当然不好


您可以通过定义自己的复制/复制赋值构造函数并确保每次复制poly2d时都会创建新的point2d来修复此问题。或者,如前所述,您可以使用std::vector来代替。

您可以尝试实现三/五规则,但我建议您使用std::vector。它基于以下原则:

具有自定义析构函数、复制/移动构造函数或 复制/移动分配操作员应专门处理所有权问题。 其他类不应具有自定义析构函数copy/move 构造函数或复制/移动赋值运算符

您可以将代码简化为以下内容:

struct point2d
{
    int x, y;
};

struct poly2d
{
    poly2d(std::vector<point2d>::size_type size);

    std::vector<point2d> p;
};
poly2d(std::vector<point2d>::size_type size)
  : p(size)
{
}
struct point2d
{
int x,y;
};
结构poly2d
{
poly2d(标准::向量::大小\类型大小);
std::向量p;
};
矢量将自动处理复制和内存管理,无需花费额外的工作。示例构造函数如下所示:

struct point2d
{
    int x, y;
};

struct poly2d
{
    poly2d(std::vector<point2d>::size_type size);

    std::vector<point2d> p;
};
poly2d(std::vector<point2d>::size_type size)
  : p(size)
{
}
poly2d(标准::向量::大小\u类型大小)
:p(尺寸)
{
}

这是因为您没有正确的复制构造函数或赋值运算符。其他人将解释具体情况。。如果您使用了
std::vector
,那么一切都会正常工作。你甚至不需要提供析构函数。让语言为你做艰苦的工作。你说的析构函数是什么意思?本地对象
temp
一旦超出范围,当然会被销毁。您将按值返回。您甚至将对象命名为
temp
。为什么你认为它不应该被破坏?您的错误与“超出范围”无关-它们是由于您违反了0/3/5规则造成的。我为=添加了一个赋值运算符,它在析构函数之后才会执行。编译器可以在从函数返回时生成一些隐藏的临时变量。一般来说,我不会试图理解糟糕的代码是如何工作的。您可能希望提供一个示例构造函数实现来帮助他。为什么在示例中使用不同的参数类型,并使用reserve而不是resize?不要让事情变得更加混乱。@NeilKirk我猜不出OP的意图。这毕竟是一个例子,他正在分配一个特定大小的数组。如果你要建议向量,至少提供一个逻辑上做同样事情的例子。啊,是的。我混淆了赋值运算符和复制构造函数……我认为void运算符=是复制构造函数,而这也只是调用复制构造函数。我不是专业程序员,所以对于业余爱好者来说,我不想在实时图形例程中使用向量,因为它们非常昂贵。正确,哦,是的,但是很昂贵。这也解释了为什么我得到两个相同的析构函数执行。浅副本按原样复制指针变量。危险的。谢谢大家的回复。