List的析构函数似乎可以工作,但是对于Element和List_iter的析构函数有问题:
未处理的异常:0xC00000FD:堆栈溢出(参数:0x00000001,0x002E2F78)。
列表:
#ifndef GUARD_List_h
#define GUARD_List_h
#include "Element.h"
#include "List_iter.h"
template <typename T>
class List {
public:
List() : begins(new Element<T>), ends(new Element<T>), Element_count(0) {
begins->t_flag = 'b';
ends->t_flag = 'e';
// double link: begins & ends
begins->next = ends;
ends->prev = begins;
}
virtual ~List() {
while (begins->next != ends) {
begins->prev = begins->next;
begins->next = begins->next->next;
delete begins->prev;
}
delete begins;
delete ends;
}
typedef List_iter<T> iterator;
iterator begin(void) const {
iterator it(begins);
return it;
}
iterator end(void) const {
iterator it(ends);
return it;
}
void push_back(const T val) {
Element<T>* elem = new Element<T>; // create: new-elem
elem->data = val; // set data
elem->prev = ends->prev; // link: new-elem to last-data-elem
ends->prev->next = elem; // link: last-data-elem to new-Element
elem->next = ends; // link: new-elem to List-end
ends->prev = elem; // link: List-end to new-elem
Element_count++; // update: when List grows
}
T at(const size_t pos) const {
return get_Element(pos)->data;
}
void del(const size_t pos) const {
Element<T>* elem = get_Element(pos); // get: Element for deletion
elem->prev->next = elem->next; // rejoin: double link
elem->next->prev = elem->prev; // rejoin: double link
delete elem;
Element_count--; // update: when List shrinks
}
void clear(void) {
Element<T>* ep = begins->next;
Element<T>* ep_next = ep->next;
while (ep->t_flag != 'e'){
delete ep;
ep = ep_next;
ep_next = ep->next;
}
begins->next = ends;
ends->prev = begins;
//begins->data = 0r;
//ends->elem_ID = 0;
Element_count = 0;
}
size_t size(void) const {
return Element_count;
}
bool empty(void) const {
if (Element_count == 0){ return true; }
else { return false; }
}
private:
Element<T>* begins; // List begins
Element<T>* ends; // List ends
size_t Element_count; // List size
Element<T>* get_Element(const size_t pos) const {
if (empty()) {
std::cerr << "No Element - Empty List";
throw;
}
if (pos < 0 || pos >= Element_count){
std::cerr << "No Element - Out of Range";
throw;
}
iterator it;
// Determine the more efficent iteration direction(forward or reverse) ?
if ((Element_count / 2) > pos) {
it = begin();
for (size_t i = 0; i <= pos; i++){
it++;
}
}
else {
it = end();
for (size_t i = size() - pos; i > 0; i--){
it--;
}
}
return it.elem;
}
};
#endif
元素:
#ifndef GUARD_Element_h
#define GUARD_Element_h
template <class T>
class List;
template <class T>
class List_iter;
template <class T>
class Element {
public:
Element() : prev(nullptr), next(nullptr), data(), t_flag(' ') {}
virtual ~Element() {
delete prev;
delete next;
}
friend List<T>;
friend List_iter<T>;
private:
Element<T> *prev;
Element<T> *next;
T data;
int elem_ID;
char t_flag;
};
#endif
List_iter:
#ifndef GUARD_List_iter_h
#define GUARD_List_iter_h
template <class T>
class List;
template <class T>
class List_iter {
public:
List_iter(Element<T>* e = nullptr) : elem(e) {}
virtual ~List_iter() {
delete elem;
}
friend List<T>;
T operator*(void){
if (elem->t_flag == 'e'){
elem = elem->prev;
}
else if (elem->t_flag == 'b'){
elem = elem->next;
}
return elem->data;
}
Element<T>* operator++(void) {
if (elem->next->t_flag == 'e'){
return nullptr;
}
elem = elem->next;
return elem;
}
Element<T>* operator--(void) {
if (elem->prev->t_flag == 'b'){
return nullptr;
}
elem = elem->prev;
return elem;
}
List_iter operator+(const int val) {
for (int i = 0; i < val; i++){
this->elem = this->elem->next;
}
return *this;
}
List_iter operator-(const int val) {
for (int i = 0; i < val; i++){
this->elem = this->elem->prev;
}
return *this;
}
bool operator!=(const List_iter& rhs) const {
return rhs.elem != elem;
}
bool operator>(const List_iter& rhs) const {
return (this->elem->elem_ID > rhs.elem->elem_ID);
}
bool operator<(const List_iter& rhs) const {
return (this->elem->elem_ID < rhs.elem->elem_ID);
}
bool operator>=(const List_iter& rhs) const {
return (this->elem->elem_ID >= rhs.elem->elem_ID);
}
bool operator<=(const List_iter& rhs) const {
return (this->elem->elem_ID <= rhs.elem->elem_ID);
}
private:
Element<T>* elem;
};
#endif
主:
#include <iostream>
#include "List.h"
int main() {
List<int> ls;
List<int>::iterator begin = ls.begin();
List<int>::iterator end = ls.end();
List<int>::iterator iter = begin;
std::cout << "Attempt to retrieve data from empty list: ls.at(3)" << std::endl;
std::cout << "--------------------------------------------------" << std::endl;
//std::cout << ls.at(3) << std::endl << std::endl;
std::cout << "Test: growing list does not invalidate iter" << std::endl;
std::cout << "-------------------------------------------" << std::endl;
std::cout << "Empty list" << std::endl << std::endl;
std::cout << "begin addr: " << &begin << " " << std::endl;
std::cout << "end addr: " << &end << " " << std::endl;
std::cout << std::endl << "Add data to list: 33 " << std::endl << std::endl;
ls.push_back(33);
std::cout << "begin addr: " << &begin << " " << std::endl;
std::cout << "end addr: " << &end << " " << std::endl;
std::cout << std::endl << "Add data to list: 856 " << std::endl << std::endl;
ls.push_back(856);
std::cout << "begin addr: " << &begin << " " << std::endl;
std::cout << "end addr: " << &end << " " << std::endl;
std::cout << "clear() " << std::endl << std::endl;
ls.clear();
std::cout << std::endl << std::endl;
std::cout << "Add data to list: 0 1 2 3 4 5 6 7 8 9" << std::endl;
std::cout << "-------------------------------------------------" << std::endl;
for (int i = 0; i != 10; i++){
ls.push_back(i);
}
std::cout << std::endl << std::endl;
std::cout << "data@ begin+4" << std::endl;
std::cout << "-------------" << std::endl;
std::cout << *(iter + 4) << std::endl;
std::cout << std::endl << std::endl;
std::cout << "data@ begin->end" << std::endl;
std::cout << "----------------" << std::endl;
iter = begin;
while (iter++){
std::cout << *iter << " ";
}
std::cout << std::endl << std::endl << std::endl;
std::cout << "data@ end->begin" << std::endl;
std::cout << "----------------" << std::endl;
iter = end;
while (iter--){
std::cout << *iter << " ";
}
std::cout << std::endl << std::endl << std::endl;
std::cout << "for/iter: begin->end" << std::endl;
std::cout << "----------------" << std::endl;
for (iter = begin; iter++;){
std::cout << *iter << " ";
}
std::cout << std::endl << std::endl << std::endl;
std::cout << "iter arith: +4 +1 -1" << std::endl;
std::cout << "--------------------" << std::endl;
iter = ls.begin();
iter = iter + 4;
std::cout << *iter << " ";
std::cout << *(iter + 1) << " ";
std::cout << *(iter - 1) << " ";
std::cout << std::endl << std::endl << std::endl;
std::cout << "data@: (0)(1)(2)(3)(4)(5)(6)(7)(8)(9)" << std::endl;
std::cout << "-------------------------------------" << std::endl;
for (int i = 0; i != 10; i++){
std::cout << ls.at(i) << " ";
}
//ls.clear();
List<std::string> ls_str;
ls_str.push_back("Hello");
ls_str.push_back("World");
return 0; // breakpoint
}
答案 0 :(得分:0)
新元素调用,因此由List拥有,因此只有List才能删除Element。 List_iter不需要析构函数,因为它只包含一个指针。