??? Класс 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.

Внимание! Это довольно старый топик, посты в него не попадут в новые, и их никто не увидит. Пишите пост, если хотите просто дополнить топик, а чтобы задать новый вопрос — начните новый.

Ответить

Вы можете использовать разметку markdown для оформления комментариев и постов. Используйте функцию предпросмотра для проверки корректности разметки.

Пожалуйста, оформляйте исходный код в соответствии с правилами разметки. Для того, чтобы вставить код в комментарий, скопируйте его в текстовое поле ниже, после чего выделите то, что скопировали и нажмите кнопку «код» в панели инструментов. Иначе ваш код может принять нечитаемый вид.

Либо производите оформление кода вручную, следующим образом:

``` #include <iostream> using namespace std; int main() { // ... } ```

Предпросмотр сообщения

Ваше сообщение пусто.