"operator +=" 行为异常的定义

cst*_*tml 0 c++ pointers class operator-overloading

简短的

我正在定义我自己的String类。除了+=我打算用来连接的定义之外,一切正常Strings

//expected behaviour
String c = "foo";
String d = "lala";

c+=d;
cout<<c;
Run Code Online (Sandbox Code Playgroud)

应该输出:

foolala
Run Code Online (Sandbox Code Playgroud)

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

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


代码

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)
        {
            //defines the initialiser
            SizeS = strlen(string);                 //find out the length of the string
            Buffer = new char[SizeS];               //allocate space for the entire string+1 for terminator
            memcpy(Buffer,string,SizeS);            //copy to buffer the whole thing
            Buffer[SizeS]=0;                        //terminate the buffer with an end character
        }

        char * GetBuffer() const { return this->Buffer; }

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


        // 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 ------------------
};

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;
}
Run Code Online (Sandbox Code Playgroud)

预期产出

foo
foofoo
foofoo
Run Code Online (Sandbox Code Playgroud)

实际产量

foo 
foofoo
foo
Run Code Online (Sandbox Code Playgroud)

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


解决方案

在阅读了评论和建议后,我想出了这个可行的解决方案。

        String& operator += (const String& to_concat)
        {
            unsigned int newSize = this->SizeS + to_concat.SizeS;
            char* p = new char[newSize];

            memcpy(p,this->Buffer,this->SizeS);
            memcpy(p+this->SizeS,to_concat.Buffer,to_concat.SizeS);

            delete[](this->Buffer);

            this->Buffer=p;
            this->SizeS=newSize;

            return *this;
        }
Run Code Online (Sandbox Code Playgroud)

Ast*_*ngs 5

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

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

+=创建一个新的、动态分配的字符串,使用来自原始两个字符串的数据,然后返回一个指向它的指针,然后您的程序将其丢弃(顺便说一下,泄漏了该新字符串)。

p您应该修改缓冲区,而不是创建和返回this(然后,通常,*this作为 a返回String&以允许链接)。

此外,+=操作员不应产生输出。


一个+运营商可以同样工作,你是怎么做到的,因为他们应该产生新的对象,但你不应该实际使用new为-你仍然有内存泄漏。尽量避免动态分配(尽管您将需要动态分配 eachStringbuffer指针指向的缓冲区)。