简体   繁体   English

String类中的重载+运算符

[英]Overloading + operator in String class

I have to implement a string class with operators [], +, +=, <<, >>, ==, !=, <, <=, >, >= but I cannot use the string object or include the library for c++. 我必须使用运算符[],+,+ =,<<,>>,==,!=,<,<=,>,> =来实现字符串类,但是我不能使用字符串对象或包含用于C ++。 Here is my code so far: 到目前为止,这是我的代码:

# define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<cstring>
#include<fstream>
using namespace std;
class MyString {
public:
    MyString();
    MyString(const char* chars);
    int length() const;
    char * getValue()const;
    ~MyString();
    //copy constructor
    MyString(const MyString&);
    MyString& operator =(const MyString& s);
    char& operator[](int i);
    MyString& operator+=(const MyString& s);
    friend ostream& operator<<(ostream&os, const MyString&s);
    friend istream& operator >> (istream&is, MyString&s);

    friend bool operator ==(const MyString& s1, const MyString& s2);
    friend bool operator <(const MyString& s1, const MyString& s2);

private:
    char* value;
    int size;
};
MyString operator+(const MyString s1, const MyString& s2);
bool operator !=(const MyString& s1, const MyString& s2);
bool operator >=(const MyString& s1, const MyString& s2);
bool operator <=(const MyString& s1, const MyString& s2);
bool operator > (const MyString& s1, const MyString& s2);
//no arguments constructor
MyString::MyString() {
    value = 0;
    size = 0;
}
//constructor
MyString::MyString(const char* chars) {
    size = strlen(chars);
    value = new char[size + 1];
    strcpy(value, chars);
}
int MyString::length()const {
    return size;
}
char* MyString::getValue()const {
    return value;
}
MyString::~MyString() {
    delete[] value;
}
//copy constructor
MyString::MyString(const MyString& s) {
    size = s.size;
    value = new char[size + 1];
    strcpy(value, s.value);
}
MyString& MyString::operator=(const MyString&s) {
    if (s.value == 0) {
        delete[] value;
        value = 0;
        size = 0;
        return *this;
    }
    if (this != &s) {
        delete[] value;
        value = new char[s.size + 1];
        strcpy(value, s.value);
        size = s.size;
    }
    return *this;
}
char& MyString::operator[](int i) {
    if (i < 0 || i >= size) {
        cout << "Please enter correct value of index" << endl;
        exit(0);
    }
    else {

        return value[i];
    }
    return value[i];
}
MyString& MyString::operator+=(const MyString& s) {
    char** temp = &value;
    *temp = new char[size];
    strcpy(value,*temp);
    strcat(value, s.getValue());

    if (size != 0) {
        delete[] temp;
    }
    size = strlen(value);
    return *this;
}
ostream& operator<<(ostream&out, const MyString&s) {
    out << s.value;
    return out;
}
istream& operator >> (istream&in, MyString&s) {
    char*ptr = new char[100];
    in >> ptr;
    s = MyString(ptr);
    delete ptr;
    return in;
}
MyString operator+(const MyString s1, const MyString& s2) {
    MyString answer;
    answer += s1;
    answer+= s2;
    return answer;
}
bool operator ==(const MyString&s1, const MyString& s2) {
    return(strcmp(s1.value, s2.value) == 0);
}
bool operator<(const MyString& s1, const MyString& s2) {
    return (strcmp(s1.value, s2.value) < 0);
}
bool operator !=(const MyString& s1, const MyString& s2) {
    return !(s1 == s2);
}
bool operator>(const MyString& s1, const MyString& s2) {
    return !(s1 == s2) && !(s1 < s2);
}
bool operator<=(const MyString& s1, const MyString& s2) {
    return s1 < s2 || s1 == s2;
}
bool operator >=(const MyString & s1, const MyString& s2) {
    return !(s1 < s2);
}
void test_copy_and_destructor(MyString S) {
    cout << "test: copy constructor and destructor calls: " << endl;
    MyString temp = S;
    cout << "temp inside function test_copy_and_destructor: " << temp << endl;
}

int main() {

    MyString st1("abc abc");
    MyString st2("9fgth");

    cout << "Copy constructor , << operator" << endl;

    MyString  st3(st1);

    cout << "st3: " << st3 << endl;

    test_copy_and_destructor(st2);

    MyString  st4;

    cout << "operator + " << endl;

    st4 = st3 + st2;

    cout << "st4: " << st4 << endl;

    cout << "st1 + st2: " << (st1 + st2) << endl;

    cout << "operators  [ ] " << endl;

    for (int i = 0; i < st2.length(); i++)
    cout << st2[i] << " ";

    cout << endl;

    cout << "operators  += , ==, != " << endl;

    st2 += st1;

    if (st3 == st1)
    cout << "st3 and st1 are identical " << endl;
    else cout << "st3 and st1 are not identical " << endl;

    if (st2 != st1)
    cout << "st2 and st1 are not identical " << endl;
    else cout << "st2 and st1 are identical " << endl;

    cout << "operators  < , <=, >, >= " << endl;

    if (st2 < st1)
    cout << "st2 < st1 " << endl;
    else cout << "st2 is not less than st1 " << endl;

    if (st1 <= st2)
    cout << "st1 <= st2 " << endl;
    else cout << "st1 is not less than or equal to st2 " << endl;

    if (st1 > st2)
    cout << "st1 > st2 " << endl;
    else cout << "not (st1 >  st2) " << endl;

    if (st1 >= st2)
    cout << "st1 >= st2 " << endl;
    else cout << "not (st1 >=  st2) " << endl;

    cout << "operator >> " << endl;

    //Open the data file
    ifstream  input("A9_input.txt");
    if (input.fail()) {
        cout << "unable to open input file A9_input.txt, Exiting..... ";
    return 0;
    }
    MyString temp1;
    MyString temp2("aaa");
    input >> temp1;
    input >> temp2;
    cout << "first element of input file: " << temp1 << endl;
    cout << "second element of input file: " << temp2 << endl;
    input.close();

    cout << "MyString says farewell....." << endl;
    return 0;
}

After reaching operator + my code reaches break point and crashes. 到达运算符+后,我的代码到达断点并崩溃。 I could tell something is wrong with my += operator code as + is using += code. 我可以说出我的+ =运算符代码有问题,因为+使用的是+ =代码。 Can someone help me figure out what is wrong with my += code? 有人可以帮我弄清楚我的+ =代码有什么问题吗?

your problem is that you are trying to change what you pointer points to be using a pointer and not pointer to pointer. 您的问题是您尝试更改指针指向的内容是使用指针而不是指针。 when you are using the new operator your pointer simply gets new adress at the heap and than the assignment you did before(char * temp = value) is irelvent. 当您使用new运算符时,您的指针只会在堆上获得新的地址,并且比您之前进行的赋值(char * temp = value)更容易。 beacuse temp gets the adress pointed by value and not value adress, than any modification on temp adress will not effect value. 因为temp获得的是地址而不是值地址所指向的地址,所以对temp地址的任何修改都不会影响值。 what you really wanna do is : 您真正想做的是:

char * temp = new char[size]
//modify temp(add the strings)
//change value to hold the modified string
value = temp;

you can also do that : 您也可以这样做:

char ** temp = &value;//now temp holds value's address.
*temp = new char[size];
//modify temp will modify value, but you need to derefrence before each use.

update 更新

you are trying to copy a larger string temp into value which casues overflow (its a good practise to use strcpy_s/strcat_s beacuse they cannot copy more than the length you give them, that should be the size of dest). 您正在尝试将较大的字符串temp复制到值中,这会导致溢出(使用strcpy_s / strcat_s是一个好习惯,因为它们不能复制的长度超过您给它们的长度,这应该是dest的大小)。

link to strcpy/strcpy_s doc : http://en.cppreference.com/w/c/string/byte/strcpy http://en.cppreference.com/w/c/string/byte/strcat 链接到strcpy / strcpy_s doc: http ://en.cppreference.com/w/c/string/byte/strcpy http://en.cppreference.com/w/c/string/byte/strcat

what you should do is : 您应该做的是:

char * temp = new char[size];
//strcpy_s(dest, length of dest, src)
strcpy_s(temp , sizeof temp, value);//copy value to temp
strcat_s(temp, sizeof temp, s.getValue());
if(value != nullptr)
  delete [] value;
value = temp;

The problem is that you are using strcpy() and strcat() to populate the old allocation, which is not large enough. 问题是您使用的是strcpy()strcat()来填充旧的分配,该分配不够大。 Therefore, the strcat() invocation attempts to write past the end of this allocation and the result is undefined behavior, which is manifesting as a crash on your system. 因此, strcat()调用尝试在分配结束后进行写操作,结果是未定义的行为,这表现为系统崩溃。

char* temp = value;
temp = new char[strlen(value) + s.length() +1];
strcpy(value, temp);  // <-- should be copying the other way
strcat(value, s.getValue()); // <-- should be copying into temp, not value
//if (size != 0) {
//  delete[]temp;
//}
size = strlen(value);
return *this;

Rewritten to solve this problem, as well as release the original string, and check for value == nullptr : 重写以解决此问题,并释放原始字符串,并检查value == nullptr

char *oldString = value == nullptr ? "" : value;

int newSize = strlen(oldString) + s.length();
char *newString = new char[newSize + 1];

strcpy(newString, oldString);
strcat(newString, s.getValue());

delete [] value;

value = newString;
size = newSize;

return *this;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM