“操作符+ =”的定义出乎意料

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

我希望你很好。

简介

我正在定义自己的String类。除了我要用于连接+=

Strings定义外,其他所有内容都正常运行
//expected behaviour
String c = "foo";
String d = "lala";

c+=d;
cout<<c;

应输出:

foolala

我有一个问题,因为它似乎可以正常工作,除了最后一点似乎没有传递指针。

这里是代码(我省略了大多数其他定义,因为我认为它们对此没有用)


代码

Class String
{

    private:
        unsigned int SizeS;
        char *Buffer;

    public:
        String():SizeS(0){}
        String(unsigned int i):SizeS(i){Buffer=new char[SizeS];}
        String(const char *string)
        {
            SizeS = strlen(string);
            Buffer = new char[SizeS+1];
            memcpy(Buffer,string,SizeS);          
            Buffer[SizeS+1]=0;
        }
        char * GetBuffer() const { return this->Buffer; }

        // this is where the issue is ------------------
        String* operator += (const String& to_concat)
        {
            unsigned int newSize = this->SizeS + to_concat.SizeS;
            String *p = new String(newSize) ;
            memcpy(p->Buffer,this->Buffer,this->SizeS);
            memcpy(p->Buffer+this->SizeS,to_concat.Buffer,to_concat.SizeS);

            std::cout<<p->Buffer<<std::endl;

            return p;
        }
        // this is where the issue ends ------------------

        String (const String& copied)
            :SizeS(copied.SizeS)
        {
            // defines how copying  works
            Buffer = new char[SizeS+1];
            memcpy(Buffer,copied.Buffer,SizeS+1);
            Buffer[SizeS+1]=0;
        }

};

std::ostream&  operator<< (std::ostream& stream, const String& other)
{
    stream << other.GetBuffer();
    return stream;
}


int main()
{
    String c="foo";
    std::cout<<c<<std::endl;
    c += c;
    std::cout<<c<<std::endl;
}

预期输出

foo
foofoo
foofoo

实际输出

foo 
foofoo
foo

问题

我在做什么错?根据我的理解,我用指针c覆盖了指针p,但似乎c并没有改变。为什么会这样?

希望您度过愉快的一天,谢谢您的时间。

c++ class pointers operator-overloading
1个回答
3
投票

因为您没有编写任何代码来更改c

没有“指针c”,即使有,也不会覆盖它。

[您的+=使用原始两个字符串中的数据创建了一个动态分配的新字符串,然后返回一个指向它的指针,您的程序随后将其丢弃(偶然地,泄漏了这个新字符串)。

代替创建并返回p,您应该修改this中的缓冲区(然后,通常,将*this作为String&返回以允许链接)。

此外,+=运算符也不应产生输出。


+运算符的工作方式与您执行此操作的方式类似,因为它们应该产生新的对象,但是您实际上不应为此使用new-仍然会发生内存泄漏。尝试避免动态分配(尽管您将需要动态分配每个Stringbuffer指针指向的缓冲区)。

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