C ++使用链表在自定义字符串类中重载+运算符

时间:2018-03-28 05:47:12

标签: c++

在与我的导师进行了相当冗长的会议并且无法提出具体的解决方案之后,我想我会回到这里寻求家庭作业的帮助。我们应该将字符串类翻译成我们自己的版本,该版本使用带有一些基本功能的链表。到目前为止,除了+运算符函数(将两个字符串加在一起)之外,一切似乎都有效。

string operator +(string& s1, string& s2);

奇怪的是,它似乎在测试时返回正确的结果,只是在调试断言失败时导致崩溃。我不知道为什么会这样,因为定义:

string operator +(string& s1, string& s2)
{
    s1 += s2;
    return s1;
}

依赖于+ =,但该运算符在main()中的测试代码没有问题。这是完整的代码:

HEADER FILE

#ifndef STRING2_H
#define STRING2_H
#include<iostream>

namespace string2
{
class string
{
private:
    struct stringList
    {
        char character;
        stringList* link;
    };

    stringList* headPtr;

public:
    // CONSTRUCTORS AND DESTRUCTOR
    string() { headPtr = NULL; };
    string(const stringList* sourcePtr);
    ~string();

    // CONSTANT MEMBER FUNCTIONS
    char getChar(const size_t position) const;
    size_t length() const;
    char operator [ ] (size_t position) const;

    // MODIFICATION MEMBER FUNCTIONS
    void operator += (const string& addend);
    void operator += (const char addend[]);
    void operator += (char addend);
    void operator =(const string& source);

    // FRIEND FUNCTIONS
    friend bool operator ==(const string& s1, const string& s2);
};

// NONMEMBER FUNCTIONS
string operator +(string& s1, string& s2);
std::ostream& operator <<(std::ostream& outs, const string& source);    
}
#endif

实施

#include "String2.h"
#include <iostream>

namespace string2
{
string::string(const stringList* sourcePtr)
{
    stringList* indexPtr;

    if (sourcePtr == NULL)
    {
        headPtr = NULL;
        return;
    }

    headPtr = new stringList;
    indexPtr = headPtr;

    indexPtr->character = sourcePtr->character;
    indexPtr->link = sourcePtr->link;
    sourcePtr = sourcePtr->link;

    while (sourcePtr != NULL)
    {
        indexPtr = indexPtr->link;
        indexPtr->character = sourcePtr->character;
        indexPtr->link = sourcePtr->link;
        sourcePtr = sourcePtr->link;
    }
}

string::~string()
{
    stringList *removePtr;;

    while (headPtr != NULL)
    {
        removePtr = headPtr;
        headPtr = headPtr->link;
        delete removePtr;
    }
}

char string::getChar(const size_t position) const
{
    stringList *indexPtr = headPtr;

    for (size_t i = 0; i < position - 1; i++)
        indexPtr = indexPtr->link;

    return indexPtr->character;
}

size_t string::length() const
{
    size_t count = 0;
    stringList* indexPtr = headPtr;

    while (indexPtr != NULL)
    {
        count++;
        indexPtr = indexPtr->link;
    }

    return count;
}

char string::operator [ ] (size_t position) const
{
    stringList* indexPtr = headPtr;

    for (size_t i = 0; i < position; i++)
        indexPtr = indexPtr->link;

    return indexPtr->character;
}

void string::operator += (const string& addend)
{
    for (int index = 0; index < addend.length(); index++)
        (*this) += addend[index];
}

void string::operator += (const char addend[])
{
    if (addend[0] == NULL)
        return;

    for (int index = 0; index < (sizeof(addend) / sizeof(addend[0])); index++)
        (*this) += addend[index];
}

void string::operator += (char addend)
{
    stringList *indexPtr = headPtr;

    if (headPtr == NULL)
    {
        headPtr = new stringList;
        headPtr->character = addend;
        headPtr->link = NULL;
        return;
    }

    while (indexPtr->link != NULL)
        indexPtr = indexPtr->link;

    indexPtr->link = new stringList;
    indexPtr->link->character = addend;
    indexPtr->link->link = NULL;
}

void string::operator =(const string& source)
{   
    if (headPtr != NULL)
    {
        delete headPtr;
        headPtr = NULL;
    }

    *this += source;
}

bool operator ==(const string& s1, const string& s2)
{
    if (s1.length() != s2.length())
        return false;

    if (s1.headPtr == NULL && s2.headPtr == NULL)
        return true;

    for (int index = 0; index < s1.length(); index++)
    {
        if (s1.headPtr->character != s2.headPtr->character)
            return false;
    }

    return true;
}

string operator +(string& s1, string& s2)
{
    s1 += s2;
    return s1;
}

std::ostream& operator <<(std::ostream& outs, const string& source)
{
    for (int index = 0; index < source.length(); index++)
            outs << source.getChar(index + 1);

    return outs;
}
}

TEST CODE(最后一行是它破坏的地方)

#include "String2.h"
#include <iostream>
#include <fstream>
using namespace string2;

int main()
{
string test, test2, test3;

std::cout << "Current length: " << test.length() << std::endl;
char add[4] = { 'a', 'b', 'c', 'd' };
test += 's'; // testing third (lowest) += operator
std::cout << "First char in string: " << test.getChar(1) << std::endl;
test += 'd';
std::cout << "Current length: " << test.length() << std::endl;
std::cout << "Second char in string:  " << test.getChar(2) << std::endl;
std::cout << "Second char in string testing [] operator: " << test[1] << std::endl;
std::cout << "Current string: " << test << std::endl;
test += add; // testing second (middle) += operator
std::cout << "Current length: " << test.length() << std::endl;
std::cout << "Current string: " << test << std::endl;

test2 += 'z';
test2 += 'y';
test += test2; // testing first (top) += operator
std::cout << "Current string: " << test << std::endl;

test = test2; // testing = operator
std::cout << "\nCurrent string: " << test << std::endl;
std::cout << "Compared to string: " << test2 << std::endl;
if (test == test2) // testing == operator
    std::cout << "\nStrings are equal" << std::endl;
else
    std::cout << "\nStrings are not equal." << std::endl;

test += 'f';
std::cout << "\nCurrent string: " << test << std::endl;
std::cout << "Compared to string: " << test2 << std::endl;

if (test == test2) // testing == operator
    std::cout << "\nStrings are equal" << std::endl;
else
    std::cout << "\nStrings are not equal." << std::endl;

std::cout << "\nTwo strings added together: " << test + test2 << std::endl; // testing + operator
}

感谢您的帮助

1 个答案:

答案 0 :(得分:0)

使用此

可以重现您的问题
int main()
{
    string test, test2;
    test += 'h';
    std::cout << "\nTwo strings added together: " << test + test2 << std::endl; // testing + operator
}

string operator +(string& s1, string& s2)
{
    s1 += s2;
    return s1;
}

operator +中,return s1返回s1的浅表副本。所以现在内部内存被s1占用,以及{{1}返回的字符串}}。在operator+() main()的末尾触发~string(),释放内部内存,然后从s1获取返回的字符串,并尝试删除已删除的内存双免费。

您需要operator+()或更好的深层副本,重新考虑operator+()的设计。