在String类中重载+运算符

时间:2017-07-13 02:50:14

标签: c++ string operator-overloading

我必须使用运算符[],+,+ =,<<,>>,==,!=,<,< =,>,> =来实现字符串类,但是我不能使用字符串对象或包含c ++库。到目前为止,这是我的代码:

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

到达操作员+我的代码到达断点并崩溃。我可以告诉我的+ =运算符代码有问题,因为+正在使用+ =代码。有人可以帮我弄清楚我的+ =代码有什么问题吗?

2 个答案:

答案 0 :(得分:0)

你的问题是你试图改变指针所指向的指针,而不是指向指针的指针。 当你使用new运算符时,你的指针只是在堆上得到新的地址,而你之前做的赋值(char * temp = value)是irelvent。 因为临时地址上的任何修改都不会影响价值,因此临时地址获取地址由价值而不是价值地址。 你真正想做的是:

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.

你也可以这样做:

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;

<强>更新

你试图将一个更大的字符串temp复制到值中,这会导致溢出(这是一个使用strcpy_s / strcat_s的好习惯,因为它们不能复制超过你给它们的长度,这应该是dest的大小)。

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

你应该做的是:

${jobs.value}

答案 1 :(得分:0)

问题是您使用strcpy()strcat()填充分配,这个分配不够大。因此,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;

重写以解决此问题,并释放原始字符串,并检查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;