C++代码报错C2280:带指针Pair类对象求和功能修复求助
修复带有指针成员的Pair类赋值错误及指针问题
报错信息
(79): 错误C2280: 'Pair &Pair::operator =(const Pair &)': 尝试引用已删除的函数 (60): 注: 编译器在此生成了'Pair::operator =' (60): 注: 'Pair &Pair::operator =(const Pair &)': 函数被隐式删除,因为'Pair'拥有用户定义的移动构造函数
问题分析
- 赋值运算符被隐式删除:C++规则中,当类定义了移动构造函数时,编译器会自动删除默认的拷贝赋值运算符。代码中
ob4 = ob1.sume(ob2);需要使用拷贝赋值运算符,因此触发错误。 - 内存分配错误:
new int(sizeof(x))实际分配的是指针大小的内存(而非单个int的大小),正确写法应为new int。 - 析构函数错误:
delete[]x;用于释放数组内存,但x是单个int的指针,应使用delete x;,否则会导致未定义行为。 - 拷贝构造函数参数非const:原拷贝构造函数参数是
Pair& ob,无法接受const对象或临时对象,应改为const Pair& ob。 - 移动构造函数未实现正确语义:原移动构造函数重新分配内存,没有接管原对象的资源,失去了移动构造的意义,应该直接转移指针并置空原对象指针。
修复后的代码
#define _CRT_SECURE_NO_WARNINGS #include <iostream> using namespace std; class Pair { int *x, *y; public: // 默认构造函数 Pair() { x = new int; y = new int; *x = 0; *y = 0; } // 带两个参数的构造函数 Pair(int a, int b) { x = new int; y = new int; *x = a; *y = b; } // 拷贝构造函数:参数改为const引用 Pair(const Pair& ob) { x = new int; y = new int; *x = *(ob.x); *y = *(ob.y); } // 移动构造函数:正确转移资源 Pair(Pair&& ob) noexcept { x = ob.x; y = ob.y; ob.x = nullptr; ob.y = nullptr; } // 委托构造函数 Pair(int a) : Pair(a, 0) {} void setX(int X) { *x = X; } void setY(int Y) { *y = Y; } int* getX() { return x; } int* getY() { return y; } // 析构函数:使用delete而非delete[] ~Pair() { delete x; delete y; } // 拷贝赋值运算符:手动实现 Pair& operator=(const Pair& ob) { if (this != &ob) { *x = *(ob.x); *y = *(ob.y); } return *this; } // 移动赋值运算符(可选,完善语义) Pair& operator=(Pair&& ob) noexcept { if (this != &ob) { delete x; delete y; x = ob.x; y = ob.y; ob.x = nullptr; ob.y = nullptr; } return *this; } // 求和函数:参数改为const引用避免不必要拷贝 Pair sume(const Pair& ob1) { Pair ob2; *(ob2.x) = *(ob1.x) + (*x); *(ob2.y) = *(ob1.y) + (*y); return ob2; } double media() { return (static_cast<double>(*x) + static_cast<double>(*y)) / 2; } }; int main() { Pair ob1, ob2(5), ob3(4, 3); ob1.setX(6); ob1.setY(7); cout << "X= " << *(ob1.getX()) << endl; cout << "Y= " << *(ob1.getY()) << endl; cout << "Media este: " << ob1.media(); cout << "\nX= " << *(ob2.getX()) << endl; cout << "Y= " << *ob2.getY() << endl; cout << "Media este: " << ob2.media(); cout << "\nX= " << *(ob3.getX()) << endl; cout << "Y= " << *(ob3.getY()) << endl; cout << "Media este: " << ob3.media(); Pair ob4, ob5, ob6; ob4 = ob1.sume(ob2); // 现在可以正常赋值 cout << "\nX= " << *(ob4.getX()) << endl; cout << "Y= " << *(ob4.getY()) << endl; }
额外说明
- 手动实现了拷贝赋值运算符,解决了原报错的核心问题。
- 优化了移动构造和移动赋值运算符,实现正确的资源转移语义,避免不必要的内存分配。
- 将
sume函数的参数改为const Pair&,减少不必要的对象拷贝,提升效率。 - 修正了内存分配和释放的错误,避免内存泄漏或未定义行为。
内容的提问来源于stack exchange,提问作者George Dulică
相关产品推荐
相关产品推荐

