首页 > 解决方案 > “操作员+=”行为异常的定义

问题描述

简短的

我正在定义我自己的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)
        {
            //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;
}

预期产出

foo
foofoo
foofoo

实际输出

foo 
foofoo
foo

问题

我究竟做错了什么?据我了解,我用指针覆盖了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;
        }

标签: c++classpointersoperator-overloading

解决方案


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

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

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

而不是创建和返回p,您应该修改缓冲区this(然后,按照惯例,返回*thisString&允许链接)。

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


+运算符的工作方式与您的工作方式类似,因为它们应该生成新对象,但您实际上不应该使用它new——您仍然会有内存泄漏。尽量避免动态分配(尽管您需要动态分配 eachStringbuffer指针指向的缓冲区)。


推荐阅读