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

浏览:23日期:2023-05-05

问题描述

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

问题解答

回答1:

代码的其中一段确实在gcc中编译不过,类型名字换一下就行了,然后就是运行没有问题,希望你把问题补充的再具体些。。比如出现错误的截图

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

还有一个值得吐槽的地方,你的+运算符太迷了,改为+=或者像+(const SString&)一样不要返回引用。。

回答2:

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,新手还望解答。

相关文章: