c++ - 使用模板时获取“删除时触发断点错误”
问题描述
我正在使用视觉工作室。
我有3节课。当我尝试打印Rectangle ABCD时没问题,但是当我将 ABCD 推入Array [rectangle] A并尝试再次打印 ABCD 时,出现“未加载 wntdll.pdb”并继续,它是“触发断点错误!! ”在删除~Rectangle()
我知道这取决于 Rectangle 类中的指针,但无法确定。
`int main(){
Array<Rectangle>A;
Rectangle a;
cout << a; //It's oke
A.PushBack(a); // problem here
cout<<a;
}`
class Point
{
private:
float _x;
float _y;
public:
float GetX() { return _x; }
float GetY() { return _y; }
public:
Point();
Point(float, float);
Point(const Point&);
~Point() {};
public:
string ToString() const;
public:
friend istream& operator>>(istream&, Point*);
friend ostream& operator<<(ostream&, const Point&);
};
Point::Point() {
_x = 1;
_y = 1;
}
Point::Point(float x, float y) {
_x = x;
_y = y;
}
Point::Point(const Point& a) {
_x = a._x;
_y = a._y;
}
string Point::ToString() const{
stringstream out;
out << "( " << _x << "," << _y << " )";
return out.str();
}
istream& operator>>(istream& in, Point* a) {
cout << "Nhap x: ";
in >> a->_x;
cout << "Nhap y: ";
in >> a->_y;
return in;
}
ostream& operator<<(ostream& out, const Point& a)
{
out << a.ToString();
return out;
}
```
class Rectangle
{
private:
Point* _topleft;
Point* _botright;
public:
void Set_topleft(Point tl) { _topleft = &tl; }
Point Get_topleft() { return *_topleft; }
void Set_botright(Point br) { _botright = &br; }
Point Get_botright() { return *_botright; }
public:
Rectangle();
Rectangle(Point*, Point*);
~Rectangle();
public:
string ToString() const;
public:
friend istream& operator>>(istream&, Rectangle&);
friend ostream& operator<<(ostream&, const Rectangle&);
};
Rectangle::Rectangle()
{
_topleft = new Point(0, 2);
_botright = new Point(3, 0);
}
Rectangle::Rectangle(Point* a, Point* b)
{
_topleft = new Point(*a);
_botright = new Point(*b);
}
Rectangle::~Rectangle()
{
delete _topleft;
delete _botright;
}
string Rectangle::ToString() const
{
stringstream out;
out << "A" << *_topleft << "+" << "D" << *_botright;
return out.str();
}
istream& operator>>(istream& in, Rectangle& a)
{
std::cout << "A( x,y ): ";
in >> a._topleft;
std::cout << "D( x,y ): ";
in >> a._botright;
return in;
}
ostream& operator<<(ostream& out, const Rectangle& a)
{
out << a.ToString();
return out;
}
```
template<class T>
class Array
{
private:
T* _a;
int _len;
public:
Array();
~Array();
public:
int length() { return _len; }
void PushBack(T);
T GetAt(int);
};
template<class T>
Array<T>::Array() {
_a = new T[128];
_len = 0;
}
template<class T>
Array<T>::~Array() {
delete[] _a;
_len = 0;
}
template<class T>
void Array<T>::PushBack(T value) {
if (_len >= 128)
{
std::cout << "Array is over size, which is 128\n";
return;
}
_a[_len] = value;
_len++;
}
template<class T>
T Array<T>::GetAt(int pos) {
return _a[pos];
}
```
解决方案
您的代码中的问题是,当您PushBack
将Rectangle
对象a
放入数组时,您会创建该对象的副本。这意味着您只需复制指针_topleft
和_botright
. 因此,在这部分代码中,您有 2 个具有相同指针的对象,因此您尝试delete
将相同的内存部分加倍。要解决这个问题,您需要定义自己的复制构造函数,它将在新对象中创建新指针。
还要记住定义自己的移动构造函数或使其对您的类禁用。
Rectangle(const Rectangle &other)
{
if(other._topleft)
_topleft= new Point(*other._topleft);
else
_topleft = nullptr;
if(other._botright)
_botright= new Point(*other._botright);
else
_topleft = nullptr;
}
下一个问题是由于 的定义void Array<T>::PushBack(T value)
。请将其更改为void Array<T>::PushBack(const T& value)
. 另外,试试Rectangle(Rectangle&& o) = delete;
推荐阅读
- excel - 创建运行 Excel 的不需要的后台进程
- javascript - 在 WooCommerce 中隐藏登录用户的登录表单
- sql - 任何人都可以帮助解释 where 子句中的 count(*)
- javascript - 如何使 Material UI 背景变强/变暗?
- python - 如何在除某些指定轴之外的所有轴上执行 TensorFlow reduce 操作,例如 reduce_sum?
- angular - 错误:inject() 必须从注入上下文中调用:ɵngcc0.ɵɵinject(ɵngcc0.Injector))
- reactjs - 更新初始化的 Material UI 输入字段 react 不会更新输入的值,而是标签与初始化的值重叠
- java - 在 Jtable 中显示图像时获取 javax.swing.ImageIcon@2f672341
- javascript - 安装 react-router-dom 失败
- list - 在 VS 代码中找到一个单词并将其替换为列表