首頁  >  問答  >  主體

C++的模板类中使用链表,却在一些环节报错说一些指针为空

C++的模板类中使用链表,却在一些环节报错说一些指针为空,但是这些地方都是限制过只有非空指针才能进的循环,没有理由会报错,求解。

#include<iostream>

using namespace std;

//链表节点
template<typename T>
struct List {
    T num;
    List* next;
};

//数组类
template<typename T>
class SString {
public:
    template<typename T>
    friend ostream& operator<<(ostream& out, const SString<T>& string);
    SString() {
        head = NULL;
    }
    SString(const SString& string) {
        List<T> *t;
        for (t = string.head; t != NULL; t = t->next) {
            *this + t->num;
        }
    }
    ~SString() {
        List<T> *t1, *t2;
        t1 = head;
        while (t1 != NULL) {
            t2 = t1->next;
            delete t1;
            t1 = t2;
        }
    }
    SString<T>& operator=(const SString<T>& string);
    SString<T>& operator+(T x);
    SString<T>& operator-(T x);
    SString<T> operator+(const SString<T>& string)const;
    SString<T> operator-(const SString<T>& string)const;
    SString<T> operator*(const SString<T>& string)const;
private:
    List<T> *head;
};

template<typename T>
SString<T>& SString<T>::operator+(T x) {
    List<T> *t1, *t2, *t3;
    t2 = new List<T>();
    t2->num = x;
    t2->next = NULL;
    if (head == NULL) {
        head = t2;
    }else{
        for (t1 = head; t1 != NULL; t1 = t1->next) {
            t3 = t1;
        }
     t3->next = t2;
    }
    return *this;
}

template<typename T>
SString<T>& SString<T>::operator-(T x) {
    List<T> *t1, *t2;
    for (t1 = head; t1 != NULL; t1 = t1->next) {
        if (t1->num == x) {
            t2->next = t1->next;
            delete t1;
            t1 = t2->next;
        }
        t2 = t1;
    }
    return *this;
}

template<typename T>
SString<T> SString<T>::operator+(const SString<T>& string) const
{
    List<T> *t;
    SString<T> s(*this);
    for (t = string.head; t != NULL; t = t->next) {
        cout << t->num;
        s.operator+(t->num);
    }
    return s;
}

template<typename T>
SString<T> SString<T>::operator-(const SString<T> & string) const
{
    SString<T> s(*this);
    List<T> *t;
    for (t = string.head; t != NULL; t = t->next) {
        s - t->num;
    }
    return s;
}

template<typename T>
SString<T> SString<T>::operator*(const SString<T> & string) const
{
    SString<T> s;
    s = *this - string;
    s = *this - s;
    return s;
}

template<typename T>
ostream& operator<<(ostream& out, const SString<T>& string)
{
    out << "{";
    List<T> *t;
    for (t = string.head; t != NULL; t = t->next) {
        out << t->num;
        if (t->next != NULL) {
            out << ",";
        }
    }
    out << "}";
    return out;
}

template<typename T>
SString<T>& SString<T>::operator=(const SString<T>& string) {
    if (this == &string) {
        return *this;
    }
    List<T> *t;
    for (t = string.head; t != NULL; t = t->next) {
        *this + t->num;
        cout << t->num;
    }
    return *this;
}

int main() {
    SString<int> s1, s2, s3, s4, s5;
    for (int i = 0; i < 3; i++) {
        int num;
        cin >> num;
        s1 = s1 + num;
    }
    cout << s1 << endl;
    for (int i = 0; i < 3; i++) {
        int num;
        cin >> num;
        s2 = s2 + num;
    }
    cout << s2 << endl;
    cout << "ss";
    (s1 + s2);
    cout << "ss";

    //cout << s3 << endl;
    //s4 = s1 - s2;
    //cout << s4 << endl;
    //s5 = s1*s2;
    //cout << s5 << endl;
    return 0;
}
迷茫迷茫2713 天前526

全部回覆(2)我來回復

  • 黄舟

    黄舟2017-04-17 13:47:08

    程式碼的其中一段確實在gcc中編譯不過,型別名字換一下就行了,然後就是運行沒有問題,希望你把問題補充的再具體些。 。例如出現錯誤的截圖

    template<typename X>
        friend ostream& operator<<(ostream& out, const SString<X>& string);

    還有一個值得吐槽的地方,你的+運算符太迷了,改為+=或像+(const SString&)一樣不要回引用。 。

    回覆
    0
  • PHP中文网

    PHP中文网2017-04-17 13:47:08

    template<typename T>
    SString<T>& SString<T>::operator+(T x) {
        List<T> *t1, *t2, *t3;
        t2 = new List<T>();
        t2->num = x;
        t2->next = NULL;
        if (head == NULL) {
            head = t2;
        }else{
            for (t1 = head; t1 != NULL; t1 = t1->next) {
                t3 = t1;
            }
         t3->next = t2;
        }
        return *this;
    }
    template<typename T>
    SString<T>& SString<T>::operator+(T x) {
        List<T> *t1, *t2, *t3;
        t2 = new List<T>();
        t2->num = x;
        t2->next = NULL;
        if (head == NULL) {
            head = t2;
        }
        else{
            for (t1 = head; t1->next != NULL; t1 = t1->next)
                ;
            t3 = t1;
            t3->next = t2;
        }
        return *this;
    }

    改成這樣vs裡就能編譯通過,原因我也不清楚,提示t3可能未初始化,但看邏輯循環體內一定會執行到

    但我改後還遇到個問題

        SString() {
            head = NULL;
        }
        SString(const SString& string) {
            List<T> *t;
            for (t = string.head; t != NULL; t = t->next) {
                *this + t->num;
            }
        }

    你這的拷貝建構子沒初始化head,但是

    template<typename T>
    SString<T> SString<T>::operator+(const SString<T>& string) const
    {
        List<T> *t;
        SString<T> s(*this);
        for (t = string.head; t != NULL; t = t->next) {
            cout << t->num;
            s.operator+(t->num);
        }
        return s;
    }

    這裡回傳s的時候會呼叫拷貝建構函數,由於head未初始化,導致

    *this + t->num;

    這句話中傳入是錯誤的head位址

    但我不清楚為什麼除了回傳值的時候,其餘時候呼叫拷貝建構函式都會將head初始化為NULL,新手還望解答。

    回覆
    0
  • 取消回覆