C++运算符重载的一个问题

来源:百度知道 编辑:UC知道 时间:2024/05/10 17:03:42
我正在做一个类,里面有一个数据成员是指针,指向一个动态分配来的数组。我现在要用友元函数重载+。
因为有指针数据成员,所以就不能在operator+函数里新建一个局部变量的类的实例来返回(返回的时候指针指向的数组会被析构掉)。
如果在operator+函数new一个类的实例的话,就没有机会析构了。
1。比如又重载了=,为了保证‘a=b’能够进行,operator=函数里面本身就要重新分配空间,于是在'a=b+c'时就多分配了一次而没有析构。
2。比如又重载了,cout << a+b;,‘a+b’用完了以后没有析构。
当然,以上的问题可以强行解决:在类里面添加一个标记某个实例是否是临时变量的数据成员,然后再在operator=和operator>> 函数里把临时的变量析构掉,但是=和>>的右式在operator=和operator>>函数里在往往是const的,所以这样做不太舒服,况且如果用户只写一句‘a+b;’(虽然这句话没什么意思)还是会无法析构。

这个问题有点像在string类里重载+,不知道有没有一个更自然的解决方法。
“对operator + 的重载可以以其中一个对象为基础,而不是新建另外一个对象。”
这样就要改变其中一个对象,你见过a=b+c时把b改掉的吗?

对“milksea - 进士出身 八级”的回答:
有指针数据成员,所以在operator+函数里新建一个auto变量的类的实例来返回时,指针是返回了,但指针指向的内容好像已经被析构掉了

对operator + 的重载可以以其中一个对象为基础,而不是新建另外一个对象。

补充:没有见具体代码,不大好说,也可能是类的设计不太好。

照你说的情况,是要把一个对象中内部分配的数组传给另一个对象,即使在原对象被析构以后还要求保存有这个数组空间,这是违反了数据封装的原则的,应该避免;如果原对象中的数组不是原对象分配的,那么这个数组空间的回收也不应该由这个对象来做,也不会出现这种问题。所以我猜测可能是类的设计不良问题。

不要用new,用个auto型的变量就可以了。这样一来返回这个auto类型的对象就行了。类似a + b这个叫临时对象,是C++自行处理的、自行调用析构函数的,不用自己操心。
C++标准规定,临时对象的寿命是一个命令行(或是一个最小作用子表达式?记不清了),这一行执行完了它就自动析构了。你要做的仅仅是把析构函数写好就可以了。

附:实验测试这个问题的办法是,在析构函数里写一个输出语句,在重载运算符的命令行后也写一个输出语句,让每次析构都可见就行了。如:

#include <iostream>

using namespace std;

class T {
public:
T operator+(T& b) {T ret(i + b.i); return ret;}
T(int a) {i = a; cout << "Cons" << i << endl;}
~T() {cout << "Dest" << i << endl;}
int i;
};

int main()
{
T a = 5, b = 6;
cout << (a + b).i << endl;
cout << "before exit." << endl;