对象的析构函数导致崩溃 我是C++中的NOOB。我有一个无论如何也解决不了的问题。为了更好地理解类和重载运算符,我编写了一段代码: #include <iostream> #include <stdlib.h> #include <stdarg.h> using namespace std; class vectmy { public: int size; int *a; vectmy(int n,int val); ~vectmy (){delete[] a; //IF I DELETE THIS PROGRAM WORKS } vectmy & operator = (const vectmy &); }; vectmy::vectmy(int n,int val){ size=n; a = new int[ n+1 ]; for (int i=0;i<n;++i){ *(a+i)=val; } } vectmy& vectmy::operator= (const vectmy& param) { for (int i=0;i<3;++i) a[i]=param.a[i]; return *this; } vectmy operator+( vectmy left, vectmy right) { vectmy result = left; for (int i=0;i<3;++i) result.a[i]=result.a[i]+right.a[i]; return result; } int main() { int b1[3]={1,2,4}; vectmy d(3,2),b(3,4),c(3,0); c=(b+d); for (int j=0; j<3; ++j)cout<<c.a[j]<<' '<<endl; return 0; } #包括 #包括 #包括 使用名称空间std; 类向量{ 公众: 整数大小; int*a; 向量(int n,int val); ~vectmy(){delete[]a;//如果我删除了这个程序,它就会工作 } 向量和运算符=(常量向量和); }; vectmy::vectmy(int n,int val){ 尺寸=n; a=新整数[n+1]; 对于(int i=0;i
在对象的析构函数导致崩溃 我是C++中的NOOB。我有一个无论如何也解决不了的问题。为了更好地理解类和重载运算符,我编写了一段代码: #include <iostream> #include <stdlib.h> #include <stdarg.h> using namespace std; class vectmy { public: int size; int *a; vectmy(int n,int val); ~vectmy (){delete[] a; //IF I DELETE THIS PROGRAM WORKS } vectmy & operator = (const vectmy &); }; vectmy::vectmy(int n,int val){ size=n; a = new int[ n+1 ]; for (int i=0;i<n;++i){ *(a+i)=val; } } vectmy& vectmy::operator= (const vectmy& param) { for (int i=0;i<3;++i) a[i]=param.a[i]; return *this; } vectmy operator+( vectmy left, vectmy right) { vectmy result = left; for (int i=0;i<3;++i) result.a[i]=result.a[i]+right.a[i]; return result; } int main() { int b1[3]={1,2,4}; vectmy d(3,2),b(3,4),c(3,0); c=(b+d); for (int j=0; j<3; ++j)cout<<c.a[j]<<' '<<endl; return 0; } #包括 #包括 #包括 使用名称空间std; 类向量{ 公众: 整数大小; int*a; 向量(int n,int val); ~vectmy(){delete[]a;//如果我删除了这个程序,它就会工作 } 向量和运算符=(常量向量和); }; vectmy::vectmy(int n,int val){ 尺寸=n; a=新整数[n+1]; 对于(int i=0;i,c++,class,destructor,C++,Class,Destructor,在操作符中+您可以 vectmy result = left; 这将调用默认构造函数和复制构造函数,其中您没有。因此将使用编译器变量,它不会为a成员分配内存。对于自动生成的复制构造函数,指针将被简单复制,使两个对象使用同一指针。当一个对象删除它时,另一个对象将使用另一个指针急诊室无效 你应该读一下 当我运行它时,它崩溃了。如果我移除析构函数,它就会工作。为什么会发生这种情况 您的操作员+在此处创建左侧的副本: vectmy result = left; 由于没有显式定义复制构造函数,编译器将
操作符中+
您可以
vectmy result = left;
这将调用默认构造函数和复制构造函数,其中您没有。因此将使用编译器变量,它不会为a
成员分配内存。对于自动生成的复制构造函数,指针将被简单复制,使两个对象使用同一指针。当一个对象删除它时,另一个对象将使用另一个指针急诊室无效
你应该读一下
当我运行它时,它崩溃了。如果我移除析构函数,它就会工作。为什么会发生这种情况
您的操作员+
在此处创建左侧的副本
:
vectmy result = left;
由于没有显式定义复制构造函数,编译器将隐式生成一个执行成员复制的构造函数
A
数据成员的单调副本意味着A
指针最终将指向两个不同的vectmy
(result
和left
)实例的相同位置,这两个指针在销毁时将删除[]
这样的双重删除会使您的程序出现未定义的行为,在您的情况下,这种行为表现为崩溃
这就是问题的关键:每当您有一个用户定义的复制构造函数、赋值运算符或析构函数时,您可能都应该定义它们中的所有
原因是您通常会定义其中一个函数,因为您正在管理某些资源(在您的情况下是内存),并且在复制、销毁或分配管理资源的对象时,您通常希望执行正确的操作
在这种特殊情况下,缺少正确的副本构造函数。您可以这样定义它:
vectmy::vectmy(vectmy const& v)
{
size=v.size;
a = new int[size];
*this = v;
}
此外,我建议您可以通过原始指针、<代码>新< /代码>和<代码>删除> /代码>(或它们的数组对应)避免手动内存管理,只要您可以,并考虑使用。
更新:
还要注意,您的运算符+
正在按值接受其参数,这意味着将复制每个参数(即,将调用复制构造函数)
由于此处实际上不需要复制,您可能希望通过引用获取参数(到const
):
按照。你需要一个复制构造函数。非常感谢你!我当然会使用std::vector,这只是一个测试,看看带有指针数据成员的类是如何运行的。但是我尝试使用这个操作符:vectmy vectmy::operator+(const vectmy param){vectmy temp(3,0);例如(int i=0;i@TommasoFerrari:很高兴它有帮助:)原因是您的运算符+
接受其参数按值传递参数时,将创建一个副本-这意味着将调用副本构造函数。这就是为什么只有在定义正确的副本构造函数时,副本构造函数才起作用。但是,您不需要在此处按值接受参数-您不需要操作符+
的参数副本。我稍微扩展了我的答案。@托马索费拉里:不客气,祝你的项目好运;)
vectmy operator + ( vectmy const& left, vectmy const& right)
// ^^^^^^ ^^^^^^