簡體   English   中英

使用鏈接列表的自定義字符串類中的C ++重載+運算符

[英]C++ Overloaded + operator in a custom string class using linked list

在與我的教練進行了相當長時間的討論后,由於無法提出具體的解決方案,我認為我會回到這里尋求作業的幫助。 我們應該將字符串類轉換為使用帶有一些基本功能的鏈表的自己的版本。 到目前為止,除+運算符功能(將兩個字符串加在一起)外,其他所有東西似乎都可以正常工作。

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

奇怪的是,它似乎在測試時返回正確的結果,只是導致調試斷言失敗而導致崩潰。 由於定義,我無法確定為什么會這樣:

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

依賴+ =,但是該運算符對main()中的測試代碼沒有任何影響。 這是完整的代碼:

頭文件

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

測試代碼(最后一行是中斷點)

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

謝謝您的幫助

您的問題是可以重現的

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以及來自返回的字符串operator+() main() ~string()的末尾觸發s1 ,釋放內部內存,然后從operator+()返回的字符串也嘗試刪除已經刪除的內存,從而導致雙重釋放。

您需要operator+()或更高級的副本,或者對operator+()設計進行重新思考。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM