??? Класс List ???
Внимание! Это довольно старый топик, посты в него не попадут в новые, и их никто не увидит. Пишите пост, если хотите просто дополнить топик, а чтобы задать новый вопрос — начните новый.
Внимание! Это довольно старый топик, посты в него не попадут в новые, и их никто не увидит. Пишите пост, если хотите просто дополнить топик, а чтобы задать новый вопрос — начните новый.
Есть у меня такой код. Что он делает? Это симбиоз подобия списка на основе работы со стеком. Есть список в который в который по очереди добавляются и удаляются элементы. Можно по очереди откорректировать элементы. Это учебный материал. Суть в другом:
list.h
#ifndef LIST_H_ #define LIST_H_ #include <iostream> // test using std::cout; // test #include <string> using std::string; struct ListItem{ string mm_n; // name string mm_fnum; // fone number ListItem() { mm_n = "no name"; mm_fnum = ""; cout << "Structure ListItem\n"; /* test */ } }; typedef ListItem Item; class List { private: enum {MAX = 3}; // max list's size Item m_items[MAX]; // list's members int top; // top of a list public: // default constructor List(); // is list empty? bool isEmpty() const; // is list full? bool isFull() const; // adding to the list bool addToList(const Item & item); // deliting from the list bool delFromList(Item & item); // calling outside function to change List's data members void visit(void (*pvisit) (Item & item)); // show list void showList() const; }; // end List
list.cpp
#include "list.h" #include <iostream> using std::cout; using std::cin; // default constructor List::List() { top = 0; cout << "Class List\n"; // test } // end constructor // is list empty? bool List::isEmpty() const { return 0 == top; } // end isEmpty //is list full? bool List::isFull() const { return MAX == top; } // end isFull // adding to the list bool List::addToList(const Item & item) { if (top < MAX){ m_items[top++] = item; return true; } else return false; } // end addToList // deliting from the list bool List::delFromList(Item & item) { if (top > 0){ item = m_items[--top]; return true; } else return false; } // end delFromList // calling outside function to change List's data members void List::visit(void (*pvisit) (Item & item)) { for (int i = 0; i < top; i++){ (*pvisit)(m_items[i]);// ЗДЕСЬ ПРОИСХОДИТ ПЕРЕДАЧА ССЫЛКИ НА ЧЛЕН КЛАССА LIST ВНЕШНЕЙ ФУНКЦИИ, КОТОРАЯ ИЗМЕНЯЕТ ДАННЫЕ КЛАССА } } // end visit // displaying the list void List::showList() const // test { cout << "\nList includes: " << top << " members.\n\n"; for (int i = 0; i < top; i++){ cout << "Name: " << m_items[i].mm_n << "\nNumber: " << m_items[i].mm_fnum << "\n\n"; } } // end showList // end class's List functions //########################################### // this functions are not in the List's scope //########################################### void setMembers(List & l, Item & i) { cout << "Enter a name: "; getline(cin, i.mm_n); cout << "Enter a fonenumber: "; getline(cin, i.mm_fnum); l.addToList(i); } // end setMembers void delMembers(List & l, Item & i) { char ch; do{ l.showList(); cout << "Delete last?\n(yes: y) (no: any key): "; (cin >> ch).get(); if ('y' == ch){ l.delFromList(i); cout << "Name: " << i.mm_n << "\nNumber: " << i.mm_fnum << "\nwas succesfully deleted.\n"; } }while (!l.isEmpty() && 'y' == ch); } // end delMembers void pvisit(Item & item) { cout << "\nCHANGES:\n\nName: " << item.mm_n << "\nChange name?\n(yes: y) (no: any key): "; char ch; (cin >> ch).get(); if ('y' == ch){ cout << "Enter the name: "; getline(cin, item.mm_n); } cout << "Number: " << item.mm_fnum << "\nChange fonenumber? (yes: y; no: n): "; (cin >> ch).get(); if ('y' == ch){ cout << "Enter fonenumber: "; getline(cin, item.mm_fnum); } } // end pvisit;
uselist.cpp
#include "list.h" #include <iostream> using std::cout; using std::cin; int main() { bool exit = true; // exit from while loop short choice; // menu's choice Item I; // creating list's member List list; // creating a list do{ cout << "1. Add to the list\n2. Delete last\n3. Display the list\n4. Change list\n0. Quit\n\nChoice: "; (cin >> choice).get(); switch(choice){ case 1: if (list.isFull()){ cout << "\nSorry the list is already full.\n\n"; } // end if else{ setMembers(list, I); } // end else break; case 2: if (list.isEmpty()){ cout << "\nSorry the list is already empty.\n\n"; } else{ delMembers(list, I); } break; case 3: list.showList(); break; case 4: if (list.isEmpty()){ cout << "\nSorry the list is empty.\n\n"; } else{ list.visit(pvisit); } break; case 0: exit = false; break; default: cout << "\nMake correct choice.\n\n"; break; } }while (exit); cout << "Bye!\n"; return 0; }
Вопрос 1: В заголовочном файле есть определение структуры
ListItem
с конструктором по умолчанию. В классеList
я объявляю массив этого типа. Можно ли таким образом инициализировать массив дабы не инициализировать его в конструкторе класса?Вопрос 2: В реализации класса
List
есть такая себе функцияvoid visit(void (*pvisit)(Item & item))
, которая в параметре имеет указатель на внешнюю функцию, которой в свою очередь по ссылке передаются данные классаList
// calling outside function to change List's data members void List::visit(void (*pvisit) (Item & item)) { for (int i = 0; i < top; i++){ (*pvisit)(m_items[i]);// ЗДЕСЬ ПРОИСХОДИТ ПЕРЕДАЧА ССЫЛКИ НА ЧЛЕН КЛАССА LIST ВНЕШНЕЙ ФУНКЦИИ, КОТОРАЯ ИЗМЕНЯЕТ ДАННЫЕ КЛАССА } } // end visit
Означает ли это то, что класс плохо «упакован» или такой трюк можно проворачивать при необходимости?
ЗАРАНЕЕ СПАСИБО.
Ответ 1: Разве оно не выдаёт тебе на консоль «Structure ListItem» в количестве 3 штук? Должно инициализироваться неявно конструктором по умолчанию.
Ответ 2: при необходимости — можно )) Этим занимается, например, алгоритм for_each из STL.
СПАСИБО!