我已经重载了<<和=运算符。为什么当我把一个对象赋值给另一个对象并试图打印它时,我得到的是打印出来的垃圾?

问题描述 投票:0回答:1

我有一个程序,有一个Length类。这个类有一个类型为int的属性size和一个类型为char的动态数组*numb。我重载了运算符<<和=,这样我就可以打印对象的值,并将一个对象的值分配给另一个对象。如果我把返回类型留在 operator = void,programm 似乎工作得很好,但如果我试图返回一个 Length 对象,我得到的是垃圾打印。为什么会这样?谢谢你。

类Length代码。

class Length
{
    int size;
    char *numb;
public:
    Length()
    {

    }
    Length(int size, char *n);
    ~Length();
    friend ostream & operator << (ostream &channel, const Length &l);
    Length operator = (const Length &x);

};

构造函数的实现:

Length::Length(int size, char  *n)
{
    this->size = size;
    numb = new char[size];

    for(int i = 0; i < size; i++)
    {
        numb[i] = n[i];
    }
}

操作符的实现 << 重载:

ostream & operator << (ostream &channel, const Length &l)
{
    channel << "Size " << l.size <<endl;
    for(int i = 0; i < l.size; i++)
    {
        channel << l.numb[i] << endl;
    }
    return channel; 
}

运算符的实现=重载:

Length Length::operator =(const Length &x)
{

    delete [] this->numb; 
    this->size = x.size;
    this->numb = new char[this->size];
    memcpy(this->numb, x.numb, this->size);
    return *this; //If I comment that line and make return type void programm works fine
}

Main:

int main()
{
    char * ch = "Hello";
    char * cx = "Hi";

    int size = strlen(ch);
    int size_x = strlen(cx);

    Length h(size, ch);
    Length x(size_x, cx);
    cout << x; //Works fine
    cout << h <<endl; //Works fine
    x = h; 
    cout << x <<endl; //Prints junk
}
c++ operators overloading
1个回答
1
投票

你应该返回这里的引用。

Length& Length::operator =(const Length &x)
{
    if (this != &x)
    {
         delete [] this->numb; 
         this->size = x.size;
         this->numb = new char[this->size];
         memcpy(this->numb, x.numb, this->size);
    }
    return *this; 
}

并添加复制构造函数。

Length(Length& len) 
{
    size = len.size;
    numb = new char[size];
    for (int i = 0; i < size; ++i)
    {
         numb[i] = len.numb[i];
    } 
}   

3
投票

根据molbdnilo的说法, 你的代码有两个问题. 第一个问题是: operator= 应该返回一个引用。当它不返回时,这并不是一个错误,但它导致的行为与赋值的正常行为不一致。我不打算在这里详述,如果你愿意,可以去查。

但如果结合你的第二个错误,你确实会出现问题。因为你返回的是 Length 按价值 operator= 你调用了 Length 复制构造函数。但是你的类没有复制构造函数,所以它使用了默认值,而这个默认值做了错误的事情。发生的情况是,当你从你的 operator=this->numb 指针会被复制到临时对象中,这个临时对象也是 operator=. 这个临时对象就会被销毁,其结果是,内存的 this->numb 是指向的被删除。这就是为什么当你打印出来的时候,你会看到一些垃圾 x,因为它的内部内存已经被释放了。

有两种可能的修复方法,返回一个来自于 operator=并为你的类写一个有效的复制构造函数。两种方法都可以解决问题,你应该同时进行。

而且你还应该阅读关于 三分法,以充分了解这个非常重要的问题。

© www.soinside.com 2019 - 2024. All rights reserved.