Модераторы: Poseidon
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [C++]Задача на наследование. 
V
    Опции темы
Mcicool
Дата 17.5.2007, 16:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 205
Регистрация: 9.10.2005

Репутация: нет
Всего: нет



Создайте класс с именем CPerson, содержащий три поля типа string для хранения имени, фамилии и отчества.
В классе создайте чистую виртуальную функцию ShowData(), выводящую на экран имя, фамилию и отчество.
Далее от класса CPerson с помощью наследования создайте два класса: CStudent, CProfessor.
К классу CStudent добавьте дополнительное поле, содержащее средний бал студента.
К классу CProfessor три поля: 1)число публикаций профессора, 2) должность (тип - перечисление) - преподаватель, старший преподаватель, доцент, профессор, 3) возраст.
Для каждого производного класса переопределите метод ShowData().
В основной программе определите массив (можно не динамический) указателей на объекты класса СPerson. Далее в цикле нужно организовать ввод студентов и профессоров вперемешку. Когда ввод будет закончен, нужно вывести информацию с помощью метода ShowData обо всех людях.

Спасибо заранее...


PM MAIL   Вверх
Fazil6
Дата 21.5.2007, 13:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1653
Регистрация: 3.5.2006
Где: Минск

Репутация: нет
Всего: 60



Код


#include <iostream>
#include <string>
#include <vector>

enum KINDEX{STUD = 0, PROF = 1};
const std::string kind_names[2] = {
                        "student",
                        "professor"
                        };

enum DOLGNOST {PREPOD = 0, STPREPOD = 1, DOCENT = 2, PROFFESS = 3};
const std::string dolg_names[4] = {
                                    "prepodavatel",
                                    "st. prepodavatel",
                                    "docent",
                                    "professor"
                                    };

//-----------------------------------
struct FIO
{
    std::string Lname;
    std::string Fname;
    std::string Mname;

    FIO(){};

    void Print() const
    {
        std::cout << Lname << " " << Fname << " " << Mname;
    }
};
//-----------------------------------
//-----------------------------------
//-----------------------------------
class CPerson
{
public:
    virtual void ShowData() const =  0;
    
    virtual ~CPerson(){};

    CPerson(const FIO &f) 
            : fio(f) {}
    
    void PrintFIO() const { fio.Print();}

private:
    FIO fio;
protected:
    static std::string razdelit;
    void InsertLeedSeparator() const; 
    void InsertEndSeparator() const;

    virtual int UserKindIndex() const = 0;

};
//-----------------------------------
std::string CPerson::razdelit("======================================");
//-----------------------------------
void CPerson::InsertLeedSeparator() const 
{
    std::cout << "\n" << razdelit << "\n" 
        << kind_names[UserKindIndex()] << "\n";
}
//-----------------------------------
void CPerson::InsertEndSeparator() const 
{
    std::cout << razdelit;
}
//-----------------------------------
//-----------------------------------
//-----------------------------------
//-----------------------------------
class CStudent : public CPerson
{
public:
    virtual void ShowData() const;

    CStudent(const FIO &f, double b):CPerson(f), srbal(b){}

private:
    double srbal;
    int UserKindIndex() const
    {
        return STUD;
    }
};

void CStudent::ShowData() const
{
    InsertLeedSeparator();
    PrintFIO();
    std::cout << "\n    Sredniy bal : " << srbal << "\n" ;
}
//-----------------------------------------------------------
//-----------------------------------------------------------
//-----------------------------------------------------------
//-----------------------------------------------------------
class CProfessor : public CPerson
{
public:
    void ShowData() const ;

    CProfessor(const FIO &f, unsigned int _vozr, unsigned int _kol_pub,
        DOLGNOST _dol)
        :CPerson(f), vozr(_vozr), kol_pub(_kol_pub), d(_dol)  {}


private:
    unsigned int vozr;
    unsigned int kol_pub;

    DOLGNOST d;

    int UserKindIndex() const
    {
        return PROF;
    }
};

void CProfessor::ShowData() const
{
    InsertLeedSeparator();
    PrintFIO();
    std::cout << "\n    Vozrast : " << vozr << "\n" ;
    std::cout << "\n    Public  : " << kol_pub << "\n" ;
    std::cout << "\n    Dolgn   : " << dolg_names[d] << "\n" ;
}
//-----------------------------------------------------------
//-----------------------------------------------------------
//-----------------------------------------------------------
FIO InputFIO()
{
    FIO f;
    std::string instr;
    std::cout << "\nInput Last name :";
    std::cin >> f.Lname; 
    std::cout << "\nInput First name :";
    std::cin >> f.Fname; 
    std::cout << "\nInput Mid name :";
    std::cin >> f.Mname; 

    return f;

}
//-----------------------------------------------------------
CProfessor* ProfessorCreator()
{
    FIO f(InputFIO());
    unsigned int v;
    std::cout << "\nInput vozr :";
    std::cin >> v;

    unsigned int kp;
    std::cout << "\nKol-vo publ :";
    std::cin >> kp;

    unsigned int di;
    std::cout << "\nInput dolgn\n(prepodavatel - 0,\n"
        "st. prepodavatel - 1,\n"
        "docent - 2,\n"
        "professor - 3 ) : ";
    std::cin >> di;
    if(di > PROFFESS) 
    { 
        std::cout << "\nNevernoe znachenie ("<< di<< ") Prinyato 0";
        di = 0;
    }
    return new CProfessor(f, v, kp , (DOLGNOST)di);
}
//----------------------------------------------------
CStudent* StudentCreator()
{
    FIO f(InputFIO());
    unsigned int v;
    std::cout << "\nInput srbal :";
    std::cin >> v;

    return new CStudent(f, v);
}
//-----------------------------------------------------
class UserContainer
{
public:
    CPerson * operator[](int i)
    {
        return vp[i];
    }
    void AddItem(CPerson * p)
    {
        vp.push_back(p);
    }
    ~UserContainer()
    {
        for(unsigned int i = 0; i < vp.size(); ++i)
        {
            delete vp[i];
            vp[i] = NULL;
        }
    }
    
    unsigned int Size(){ return vp.size();}
private:
    std::vector<CPerson *> vp;
};
//-----------------------------------------------------------------
int InputIndK()
{
    int x;
    std::cout << "Input (student - " << STUD << 
        ", prof - " << PROF <<", exit - any more) : ";
    std::cin >> x;
    return x;
}
//----------------------------------------------------------------
void main()
{
    UserContainer uc;

    std::cout << "\nVvod danyh\n";
    int x = InputIndK();
    while((x == STUD) || (x == PROF))
    {
        switch(x)
        {
            case STUD: uc.AddItem(StudentCreator()) ; break;
            case PROF: uc.AddItem(ProfessorCreator()) ; break;
            default : break;

        }
        std::cout << "\n======================\n";

        x = InputIndK();
    }

    std::cout << "\nVvod okonchen\nVyvod danyh\n";
    for(unsigned int i = 0; i < uc.Size() ; ++i)
    {
        uc[i]->ShowData();
    }
    std::cout << "\n";
}


Это сообщение отредактировал(а) Fazil6 - 21.5.2007, 13:40
PM MAIL   Вверх
Xenon
Дата 21.5.2007, 14:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1529
Регистрация: 12.4.2006

Репутация: 19
Всего: 50



Если делать чисто по заданию ... жесть получается smile) Вперемешку так вводить ... ну сделал чтобы по вводился профессор/студент smile)
Код

#include <iostream>
#include <algorithm>
#include <string>
#include <functional>

namespace univer_base
{
    using std::string;
    using std::cout;
    using std::cin;
    using std::endl;

    class CPerson
    {
    protected:
        string m_name;
        string m_surname;
        string m_patronymic;
    public:
        virtual void ShowData() = 0 ;  
        CPerson():m_name("N/A"),m_surname("N/A"),m_patronymic("N/A"){}
        CPerson(const string& name, const string surname, const string patronymic):m_name(name),m_surname(surname),m_patronymic(patronymic){}
        virtual ~CPerson() {}

    };

    class CStudent: public CPerson
    {
    private:
        double m_average_mark;
    public:
        void ShowData()
        {
            cout << "Name: " << m_name << endl;
            cout << "Surname: " << m_surname << endl;
            cout << "Patronymic: " << m_patronymic << endl;
            cout << "Average mark: " << m_average_mark << endl;
        }
        CStudent(){}
        CStudent(const string& name, const string surname, const string patronymic, double average_mark):CPerson(name,surname,patronymic),m_average_mark(average_mark){}
    };

    enum post_name { lecturer, senior_lecturer, associate_professor, professor };

    class CProfessor: public CPerson
    {
    private:
        int m_pub_count;
        post_name m_post;
        int m_age;
    public:
        void ShowData()
        {
            cout << "Name: " << m_name << endl;
            cout << "Surname: " << m_surname << endl;
            cout << "Patronymic: " << m_patronymic << endl;
            cout << "Count of publications: " << m_pub_count << endl;
            cout << "Post: ";
            switch (m_post)
            {
            case 0: cout << "Lecturer\n";
                break;
            case 1: cout << "Senior Lecurer\n";
                break;
            case 2: cout << "Associare Professor\n";
                break;
            case 3: cout << "Professor\n";
                break;
            default: cout << "Wrong Profession\n";
                break;
            }
            cout << "Age: " << m_age;
        }
        CProfessor(const string& name, const string surname, const string patronymic, int pub_count, post_name post, int age):CPerson(name,surname,patronymic),m_pub_count(pub_count),m_post(post),m_age(age){}
    }; 
}

const int SIZE = 4;

using namespace univer_base;

int main(int argc, char* argv[])
{
    CPerson* arr[SIZE] = { 0 };
    for (int i = 0; i < SIZE; ++i)
    {
        std::string name;
        std::string surname;
        std::string patronymic;
        if (i & 1) //Если нечетный
        {
            //Студент
            double average = 0.0;
            cout << "Student\n";
            cout << "Enter name: ";
            cin >> name;
            cout << "Enter surname: ";
            cin >> surname;
            cout << "Enter patronymic: ";
            cin >> patronymic;
            cout << "Enter average mark: ";
            cin >> average;
            arr[i] = new CStudent(name, surname, patronymic, average);
        }
        else
        {
            //Профессор
            int pub_count = 0;
            int age = 0;
            post_name post;
            cout << "Professor\n";
            cout << "Enter name: ";
            cin >> name;
            cout << "Enter surname: ";
            cin >> surname;
            cout << "Enter patronymic: ";
            cin >> patronymic;
            cout << "Enter the number of publications: ";
            cin >> pub_count;
            cout << "Choose the pos of professor: 1) Lecturer 2) Senior Lecuterer 3) Associate Professor 4) Professor : ";
            int var = 0;
            cin >> var;
            switch(var)
            {
            case 0: post = associate_professor;
                break;
            case 1: post = lecturer;
                break;
            case 2: post = professor;
                break;
            case 3: post = senior_lecturer;
                break;
            default: break;
            }
            cout << "Enter yout age: ";
            cin >> age;
            arr[i] = new CProfessor(name, surname, patronymic, pub_count, post, age);
        }
    }
    std::for_each(arr, arr + SIZE, std::mem_fun(&CPerson::ShowData) );
    for (int i = 0; i < SIZE; ++i) delete arr[i];
    std::cin.sync();
    std::cin.get();
    return 0;
}


Это сообщение отредактировал(а) Xenon - 21.5.2007, 18:07


--------------------
user posted image  
PM MAIL   Вверх
Mcicool
Дата 23.5.2007, 14:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 205
Регистрация: 9.10.2005

Репутация: нет
Всего: нет



Спасибо большое. Но есть вопросы. 
--> Xenon. ЗАчем вы использовали свое простарнство имен? Можно ли как нибудь без этого обойтись ? ))
Зачем виртуальный деструктоР?
И что делает     std::for_each(arr, arr + SIZE, std::mem_fun(&CPerson::ShowData) ); строчка? Первый раз вижу. Что делают эти функции?
PM MAIL   Вверх
Xenon
Дата 23.5.2007, 16:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1529
Регистрация: 12.4.2006

Репутация: 19
Всего: 50



Mcicool
1) Пространство имено для того, чтобы объединить по смыслу связанные классы в одно, как бы, целое. Можешь убрать : сотри "using namespace univer_base;" и объявление пространства имен. Думаю смогешь
2) Виртульный деструктор обычно всегда делают в классах, которые замешаны в наследовании для того чтобы правильно особождать ресурсы классов.
3) std::for_each(InIter start, InIter end, Func f) - функция и стандартной библиотеки STL, которая вызывает функцию f для каждого объекта в контейнере, начало которого задается итератором start и конец итератором end (в нашем случае начало контейнера(у нас массив arr) - указатель на его первый элемент, но можем использовать просто имя массива в качестве адресса на первый элемент). std::mem_fun() предназначена для того, чтобы мы имели возможность использовать функции-члены классов в алгоритмах библиотеки STL - просто алгоритмы из этой библиотеки кушают только указатели на свободные функции. Пу сути-то эта строчка эквивалетна строчке:
Код

 for (int i = 0; i < SIZE; ++i) arr[i]->ShowData();

Просто я уже привык использовать обильно STL smile Если устрашает, можешь заменить, тогда и заголовочный файл #include <functional> на понадобится.
В итоге, если убрать то, что тебя пугает, получится:
Код

#include <iostream>
#include <string>

using std::string;
using std::cout;
using std::cin;
using std::endl;

class CPerson
{
protected:
    string m_name;
    string m_surname;
    string m_patronymic;
public:
    virtual void ShowData() = 0 ;  
    CPerson():m_name("N/A"),m_surname("N/A"),m_patronymic("N/A"){}
    CPerson(const string& name, const string surname, const string patronymic):m_name(name),m_surname(surname),m_patronymic(patronymic){}
    virtual ~CPerson() {}

};

class CStudent: public CPerson
{
private:
    double m_average_mark;
public:
    void ShowData()
    {
        cout << "Name: " << m_name << endl;
        cout << "Surname: " << m_surname << endl;
        cout << "Patronymic: " << m_patronymic << endl;
        cout << "Average mark: " << m_average_mark << endl;
    }
    CStudent(){}
    CStudent(const string& name, const string surname, const string patronymic, double average_mark):CPerson(name,surname,patronymic),m_average_mark(average_mark){}
};

enum post_name { lecturer, senior_lecturer, associate_professor, professor };

class CProfessor: public CPerson
{
private:
    int m_pub_count;
    post_name m_post;
    int m_age;
public:
    void ShowData()
    {
        cout << "Name: " << m_name << endl;
        cout << "Surname: " << m_surname << endl;
        cout << "Patronymic: " << m_patronymic << endl;
        cout << "Count of publications: " << m_pub_count << endl;
        cout << "Post: ";
        switch (m_post)
        {
        case 0: cout << "Lecturer\n";
            break;
        case 1: cout << "Senior Lecurer\n";
            break;
        case 2: cout << "Associare Professor\n";
            break;
        case 3: cout << "Professor\n";
            break;
        default: cout << "Wrong Profession\n";
            break;
        }
        cout << "Age: " << m_age;
    }
    CProfessor(const string& name, const string surname, const string patronymic, int pub_count, post_name post, int age):CPerson(name,surname,patronymic),m_pub_count(pub_count),m_post(post),m_age(age){}
}; 

const int SIZE = 4;

int main(int argc, char* argv[])
{
    CPerson* arr[SIZE] = { 0 };
    for (int i = 0; i < SIZE; ++i)
    {
        string name;
        string surname;
        string patronymic;
        if (i & 1) //Если нечетный
        {
            //Студент
            double average = 0.0;
            cout << "Student\n";
            cout << "Enter name: ";
            cin >> name;
            cout << "Enter surname: ";
            cin >> surname;
            cout << "Enter patronymic: ";
            cin >> patronymic;
            cout << "Enter average mark: ";
            cin >> average;
            arr[i] = new CStudent(name, surname, patronymic, average);
        }
        else
        {
            //Профессор
            int pub_count = 0;
            int age = 0;
            post_name post;
            cout << "Professor\n";
            cout << "Enter name: ";
            cin >> name;
            cout << "Enter surname: ";
            cin >> surname;
            cout << "Enter patronymic: ";
            cin >> patronymic;
            cout << "Enter the number of publications: ";
            cin >> pub_count;
            cout << "Choose the pos of professor: 1) Lecturer 2) Senior Lecuterer 3) Associate Professor 4) Professor : ";
            int var = 0;
            cin >> var;
            switch(var)
            {
            case 0: post = associate_professor;
                break;
            case 1: post = lecturer;
                break;
            case 2: post = professor;
                break;
            case 3: post = senior_lecturer;
                break;
            default: break;
            }
            cout << "Enter yout age: ";
            cin >> age;
            arr[i] = new CProfessor(name, surname, patronymic, pub_count, post, age);
        }
    }
    for (int i = 0; i < SIZE; ++i) arr[i]->ShowData();
    for (int i = 0; i < SIZE; ++i) delete arr[i];
    cin.sync();
    cin.get();
    return 0;
}



--------------------
user posted image  
PM MAIL   Вверх
Mcicool
Дата 27.5.2007, 16:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 205
Регистрация: 9.10.2005

Репутация: нет
Всего: нет



Последние вопросы, если можно:
1 - virtual void ShowData() = 0; 
ЗАчем присвоение нуля ??
2 -  Что означает arr[i]->ShowData() ??
3 - Что делает cin.sync(); ??
PM MAIL   Вверх
Xenon
Дата 27.5.2007, 17:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1529
Регистрация: 12.4.2006

Репутация: 19
Всего: 50



Mcicool
  • Цитата
    В классе создайте чистую виртуальную функцию ShowData()

    Вот это
    Код

    virtual void ShowData() = 0; 

    Это не просто виртуальная функция (virtual), а ЧИСТАЯ виртуальная функция, очем свидетельствует '= 0' на конце. Из-за этого класс ставится абстрактным - его нельзя создать и из-за этого все производные класса обязаны реализовать эту функцию у себя. 
    Просто вид записи такой виртуальной функции.
  •  Так как массив arr хранит УКАЗАТЕЛИ на объекты типа CPerson мы не можем обращаться к объектам непосредственно, то есть так:
    Код

    arr[i].ShowData();

    Поэтому мы должны испольлзовать оператор -> и написать
    Код

    arr[i]->ShowData();

    Данный оператор существует для удобства и он аналогичен конструкции:
    Код

    (*arr[i]).Show_Data();
  •  std::cin.sync(), грубо говоря, из потока ввода выбрасывает мусор. Просто дальше идет функция std::cin.get(), которая ожидает от пользователя ввода символа - это я сделал для удобства,  чтобы ты результат успел посмотреть, а дальше жмешь любую кнопку и ENTER и приложение завершается (ну как обычно "Press any key and ENTER to exit");
    Просто в поток может попасть какой-то мусор, который std::cin.get() воспримет за твой ввод - таким образом ввести тебе ничего предложено не будет и программа просто завершится и ты на результаты ее работы так и не посмотришь smile



--------------------
user posted image  
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Центр помощи"

ВНИМАНИЕ! Прежде чем создавать темы, или писать сообщения в данный раздел, ознакомьтесь, пожалуйста, с Правилами форума и конкретно этого раздела.
Несоблюдение правил может повлечь за собой самые строгие меры от закрытия/удаления темы до бана пользователя!


  • Название темы должно отражать её суть! (Не следует добавлять туда слова "помогите", "срочно" и т.п.)
  • При создании темы, первым делом в квадратных скобках укажите область, из которой исходит вопрос (язык, дисциплина, диплом). Пример: [C++].
  • В названии темы не нужно указывать происхождение задачи (например "школьная задача", "задача из учебника" и т.п.), не нужно указывать ее сложность ("простая задача", "легкий вопрос" и т.п.). Все это можно писать в тексте самой задачи.
  • Если Вы ошиблись при вводе названия темы, отправьте письмо любому из модераторов раздела (через личные сообщения или report).
  • Для подсветки кода пользуйтесь тегами [code][/code] (выделяйте код и нажимаете на кнопку "Код"). Не забывайте выбирать при этом соответствующий язык.
  • Помните: один топик - один вопрос!
  • В данном разделе запрещено поднимать темы, т.е. при отсутствии ответов на Ваш вопрос добавлять новые ответы к теме, тем самым поднимая тему на верх списка.
  • Если вы хотите, чтобы вашу проблему решили при помощи определенного алгоритма, то не забудьте описать его!
  • Если вопрос решён, то воспользуйтесь ссылкой "Пометить как решённый", которая находится под кнопками создания темы или специальным флажком при ответе.

Более подробно с правилами данного раздела Вы можете ознакомится в этой теме.

Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Poseidon, Rodman

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Центр помощи | Следующая тема »


 




[ Время генерации скрипта: 0.0814 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.