C++ 为什么d';tor被称为';T
我试图初始化我自己的int数组的类,但运算符重载中的某些东西不起作用,因为某些原因,我的对象的d'tor在我希望它之前被调用,这使我的代码崩溃:C++ 为什么d';tor被称为';T,c++,class,C++,Class,我试图初始化我自己的int数组的类,但运算符重载中的某些东西不起作用,因为某些原因,我的对象的d'tor在我希望它之前被调用,这使我的代码崩溃: #include "stdafx.h" #include "Array.h" int _tmain(int argc, _TCHAR* argv[]) { Array arr(6); arr[3] = 6; //code crashes here printf("%d\n", arr[0]); return 0; }
#include "stdafx.h"
#include "Array.h"
int _tmain(int argc, _TCHAR* argv[])
{
Array arr(6);
arr[3] = 6; //code crashes here
printf("%d\n", arr[0]);
return 0;
}
现在上课:
头文件:
#pragma once
#include <malloc.h>
class Array
{
public:
//ctor dtor and operator overloading
Array(int);
Array(int *, int);
~Array();
Array operator[](int i);
//here memebers are defined
int *arr;
int size;
};
完成此功能后,我的对象将被d'tor删除
Array Array::operator[] (int i){
for (int j=0; j < i; ++j)
{
++(this->arr);
}
return *this;
}
Array数组::运算符[](int i){
对于(int j=0;jarr);
}
归还*这个;
}
因为操作符[]
函数按值返回一个数组
对象。这意味着,当您执行赋值arr[3]=6
时,运算符返回该的一个副本,然后编译器从整数6
隐式创建一个数组对象(因为它有一个匹配的构造函数),而赋值突然看起来像
arr[3] = Array(6);
在某些地方,临时数组对象(由操作符[]
函数返回的对象,以及编译器在赋值的右侧创建的对象)必须被销毁,但到那时,多个对象都使用相同的指针arr
。第一个临时对象被销毁,它删除指针,留下一个无效指针的所有其他对象。然后,下一个临时对象被销毁,并尝试删除现在无效的指针。砰,你撞车了
要解决这个问题,您需要做两件事。第一个是认识到操作符[]
函数返回的类型错误,它应该返回对所包含数组元素的引用:
int& Array::operator[](size_t const i)
{
return arr[i];
}
你需要做的第二件事是阅读
此外,为了防止编译器错误地从int
值构造对象,您应该将构造函数标记为显式:
explicit Array(int);
主要问题
无论代码中存在其他问题,您的操作员[]
的签名都是错误的:
Array Array::operator[] (int i){
...
}
这里不返回数组的元素!而是返回一个全新的数组。因此,在您的错误语句中,将构造一个新的临时数组,并在封闭表达式的末尾销毁它
试试这个。至少它不会立即崩溃:
int& Array::operator[] (int i){
return arr[i];
}
撞车原因
不幸的是,您使用malloc()
分配arr。不要在C++中这样做,而是使用<代码>新[]/CODE。这本身不会导致崩溃。但除此之外,您还可以在析构函数中使用delete
它是malloc()
/free()
或new
/delete
或new[]
/delete[]
任何其他组合都是未定义的行为(当临时数组被破坏时,这会导致原始代码崩溃)
请按如下方式更正此问题:
Array::Array(int g = 1) :size(g) //diplomatic value for size =1
{
arr = new int[size];
}
Array::~Array()
{
delete[] arr;
}
它将编译并运行:
其他严重问题
最后,更糟糕的是,原始的索引操作符返回*this
,使其成为现有数组的克隆。这个问题现在已经解决了。但是,如果要制作阵列的任何副本,则会遇到另一个问题:
这将导致在两个位置使用arr
指针。gests destructed的第一个数组将使原始数组中使用的arr
指针无效。对其arr
的任何后续解引用都将是未定义的行为
这在我的在线演示中还没有解决,所以我强烈建议大家阅读一下这些代码都没有任何意义。但是你最大的问题是你没有正确地遵循三的规则。事实上,这段代码非常棒。不是为了它的预期目的,而是作为一个例子。由于不可思议的原因,这段代码似乎结构良好,但几乎每一部分都做了一些与常见习惯用法和期望完全不同的事情。@ItayBraha操作符[]
到底应该做什么?!它将arr
增加几次,然后返回*this
..@ItayBraha一个合理的实现将返回int&
,并且不会对arr
进行任何更改。我觉得你不知道你的实现是做什么的。说真的——这段代码有太多错误,也许你应该看看一个正确实现的数组类应该是什么样子的,然后从中学习。这比试图猜测它应该是什么样子,并根据猜测和假设编写临时代码更有价值。
Array::Array(int g = 1) :size(g) //diplomatic value for size =1
{
arr = new int[size];
}
Array::~Array()
{
delete[] arr;
}