Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 14, средняя оценка - 4.71
Наталья1204
0 / 0 / 0
Регистрация: 30.08.2011
Сообщений: 4
#1

Виртуальные функции - C++

31.08.2011, 13:43. Просмотров 1801. Ответов 21
Метки нет (Все метки)

Составить программу в С Buildere. Объявить базовый класс с именем person {имя, возраст, группа}. Определить функцию show (), которая отображает информацию о человеке, как виртуальную функцию. Объявить производный класс student = {имя, возраст, группы, департамента}. Переопределить функцию show (), которая показывает студентов в порядке убывания по годам. ХЕЕЕЛП!!!!
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
31.08.2011, 13:43
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Виртуальные функции (C++):

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

виртуальные функции
сделать какой либо из методов класса виртуальным #include<iostream.h>...

виртуальные функции
Всем привет, помогите с исправлением функции #include<iostream.h>...

Виртуальные функции
Объясните строку 106 И еще, почему перед каждой x1 x2 y стоит звездочка. Я...

виртуальные функции
Помогите плиз с вертуальными функциями. Некак немогу понят вот эту задачу: ...

Виртуальные функции в С++
Здравствуйт. Помогите осмыслить доконца вирт. ф-ции. После прочтения...

21
ForEveR
В астрале
Эксперт С++
7994 / 4753 / 651
Регистрация: 24.06.2010
Сообщений: 10,547
Завершенные тесты: 3
31.08.2011, 13:50 #2
Нехило так. Интересно. От человека значит наследуется класс студент, а затем оказывается что студентов (в классе студент) должно быть более одного, дабы переопределить функцию show по заданию. Бред.
1
Bers
Заблокирован
31.08.2011, 14:09 #3
1. Создаём класс Персоны, закладываем в него вирт. диструктор, вирт функцию Показа.
2. Наследуем студентов от персон.
3. Добавляем новое поле "департамента".
4. Добавляем статический ассоциативный массив мультимап<возвраст_студента, Указатель_на_этого_студента>

5. В конструкторе студентов реализуем автоматическую регистрацию нового студента в статическом мультемапе.

6. Создадим у студентов функцию: ПоказатьСебя(); //которая выдаст на экран информацию об этом студенте.

7. Переопределяем виртуальную функцию показа, которая пробежится по мультимапу, и дергая из него указатели студентов, каждому студенту сделает: pStudents -> ShowMe();

8. После того, как все студенты отчитались о себе, добавим в конце послание преподавателю: ТАК ДЕЛАТЬ НЕЛЬЗЯ! СТУДЕНТЫ НЕ ДОЛЖНЫ ЗНАТЬ О СУЩЕСТВОВАНИИ ДРУГИХ СТУДЕНТОВ. ОШИБКА АРХИТЕКТУРЫ.
2
AzaKendler
214 / 116 / 14
Регистрация: 30.05.2011
Сообщений: 1,772
31.08.2011, 16:46 #4
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#include <iostream>
#include <string>
#include <map>
using std::iterator;
using std::multimap;
using std::make_pair;
using std::string;
using std::cout;
 
class Person
{
public:
 
    Person(){};
    virtual ~Person(){};
    virtual void Show(void)=0;
    string age;
    string name;
};
 
static multimap<string,Person*> MAP;
 
 
class Stud : public Person
{
 
public:
    Stud(string ag, string nam)
    {
        
        age =ag;
        name = nam;     
        MAP.insert(make_pair<string,Person*>(age,this));
 
    
        
    };
    ~Stud(){};
    multimap<string,Person*>::iterator IT;
 
    void Show(){ShowMe();};
    void ShowMe()
    {
        IT = MAP.begin();
        while(IT!=MAP.end())
        {       
 
            cout<<IT->first<<"  "<<IT->second->name<<"\n";
            IT++;
        }
        IT = MAP.begin();       
    };
    
};
 
 
int _tmain(int argc, _TCHAR* argv[])
{
    
Stud a("14","Ivan");
Stud b("13","Ivan");
Stud c("12","Ivan");
Stud d("13","Ivan");
a.Show();
 
    return 0;
    
}
Берсовский вариант
0
AzaKendler
214 / 116 / 14
Регистрация: 30.05.2011
Сообщений: 1,772
31.08.2011, 16:48 #5
выход
0
Изображения
 
ForEveR
В астрале
Эксперт С++
7994 / 4753 / 651
Регистрация: 24.06.2010
Сообщений: 10,547
Завершенные тесты: 3
31.08.2011, 16:58 #6
Делать нечего...

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include <iostream>
#include <map>
#include <functional>
#include <iterator>
#include <string>
#include <iostream>
 
class Person
{
public:
   Person(std::string name, short age, std::string group):name_(name), age_(age), group_(group)
   {
   }
   virtual ~Person() { }
   std::string get_name() const {return name_;}
   short get_age() const {return age_;}
   std::string get_group() const {return group_;}
   virtual void show(std::ostream& os) const
   {
       os << "Name: " << name_ << std::endl
           << "Age: " << age_ << std::endl
           << "Group: " << group_ << std::endl;
   }
protected:
   std::string name_;
   short age_;
   std::string group_;
};
 
class Student:public Person
{
public:
   Student(const std::string& name, short age, const std::string& group, const std::string& dep):
      Person(name, age, group), departement_(dep)
   {
       students.insert(std::make_pair(age, this));
   }
   std::string get_departement() const {return departement_;}
   virtual void show(std::ostream& os) const
   {
       for (std::multimap<short, const Student*, std::greater<short> >::const_iterator iter = students.begin(); iter != students.end(); ++iter)
       {
            iter->second->show_me(os);
       }
   }
private:
   static std::multimap<short, const Student*, std::greater<short> > students;
   std::string departement_;
   void show_me(std::ostream& os) const
   {
       Person::show(os);
       os << "Departement: " << departement_ << std::endl;
   }
};
 
std::multimap<short, const Student*, std::greater<short> > Student::students;
 
int main()
{
    Student stud("Vasya", 18, "1A", "BD");
    Student stud2("Vasya2", 19, "1B", "BD");
    Student stud3("Vasya3", 18, "1C", "FD");
    Student stud4("Vasya4", 17, "1D", "FD");
    stud4.show(std::cout);
}
Но препода за такое задание надо уничтожить.
0
AzaKendler
214 / 116 / 14
Регистрация: 30.05.2011
Сообщений: 1,772
31.08.2011, 17:07 #7
черт департамент забыл

Добавлено через 1 минуту
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
 
#include <iostream>
#include <string>
#include <map>
using std::iterator;
using std::multimap;
using std::make_pair;
using std::string;
using std::cout;
 
class Person
{
public:
 
        Person(){};
        virtual ~Person(){};
        virtual void Show(void)=0;
        string age;
        string name;
        string department;
};
 
static multimap<string,Person*> MAP;
 
 
class Stud : public Person
{
 
public:
        Stud(string ag, string nam, string dept)
        {
                
                age =ag;
                name = nam;  
                department = dept;
                MAP.insert(make_pair<string,Person*>(age,this));
 
        
                
        };
        ~Stud(){};
        multimap<string,Person*>::iterator IT;
 
        void Show(){ShowMe();};
        void ShowMe()
        {
                IT = MAP.begin();
                while(IT!=MAP.end())
                {               
 
                        cout<<IT->first<<"  "<<IT->second->name<<"  "<<IT->second->department<<"\n";
                        IT++;
                }
                IT = MAP.begin();               
        };
        
};
 
 
int _tmain(int argc, _TCHAR* argv[])
{
        
Stud a("14","Ivan","sales");
Stud b("13","Ivan","tools");
Stud c("12","Ivan", "wh");
Stud d("13","Ivan","manger");
a.Show();
 
        return 0;
        
}
0
Bers
Заблокирован
31.08.2011, 17:09 #8
Цитата Сообщение от AzaKendler Посмотреть сообщение
Берсовский вариант
Не-не! Надо через for_each студентиков перебирать. Так круче))
0
AzaKendler
214 / 116 / 14
Регистрация: 30.05.2011
Сообщений: 1,772
31.08.2011, 17:11 #9
Bers, ну извини. пока только так.)
0
Bers
Заблокирован
31.08.2011, 17:59 #10
Цитата Сообщение от AzaKendler Посмотреть сообщение
Bers, ну извини. пока только так.)
Ну это ладно. Но обратите внимание:

Во-первых имя - МАП. Это никуда не годится. Оно не отражает сути. Что именно хранит внутри себя этот мап?

Во-вторых, как именно создан статический мультимап у вас?
Идеологически, он является внутренней частью реализации класса студентов. Но у вас он вообще вынесен за пределы класса, и доступ к нему можно получить из любой точки программы. Это - архитектурный промах. Он должен быть в приватной зоне класса-хозяина.

В-третьих, ключевые слова const. У вас их вообще нигде нету. А должны быть! Мы ведь боремся за гигиеническую чистоту нашего кода, правда ведь?

/зы присмотритесь к варианту господина ForEveRa.
Просто сравните. Вроде бы все тоже самое, но у него сразу чувствуется, что код писался
солидным, опытным программистом.

/ззы не сочтите за умника, я далеко не великий программист. И сам ещё только-только учусь.

Добавлено через 5 минут
Единственное, что мне не понятно в коде господина ForEveR, так это гм...

C++
1
2
3
4
5
6
virtual void show(std::ostream& os) const
   {
       os << "Name: " << name_ << std::endl
           << "Age: " << age_ << std::endl
           << "Group: " << group_ << std::endl;
   }
Если известно, что информация будит выводиться при помощи стандартного потока, то зачем было передавать объект потока в качестве аргумента?
Не проще ли, использовать обычный cout тогда?
1
ForEveR
В астрале
Эксперт С++
7994 / 4753 / 651
Регистрация: 24.06.2010
Сообщений: 10,547
Завершенные тесты: 3
31.08.2011, 19:25 #11
Bers, проще, но не дальновидно. А что, если в файл придется выводить?
0
AzaKendler
214 / 116 / 14
Регистрация: 30.05.2011
Сообщений: 1,772
31.08.2011, 20:30 #12
Bers, ну все верно. много чего можно довести. Абсолютно со всем согласен. так это был просто выстрел от бедра от АзаКендлер)) когда все матерые кодеры послали тетю и только один Берс сформировал ТЗ и включил зеленый свет. А так..дешево и сердито. Разве нет? Ну похвали уже..Я ж учу еще.
И вообще, конечно однозначно надо все делать по науке, но не в ущерб общей мысли. тут где то была темка там просили составить Хэллоу уорд! От там парни поизгалялись. И так и эдак выкручивали с этой надписью. Думаю чем проще и ближе к заданию тем лучше. Надо вывести - на.

Добавлено через 17 минут
Цитата Сообщение от ForEveR Посмотреть сообщение
std::string name, short age, std::string group
ну и если честно и объективно, если std::string например часто проходит по тексту, разве не правильней его вынести в using?
просто я как новичок могу подумать что так и надо делать всегда полные объявления
0
Jupiter
Каратель
Эксперт С++
6568 / 3989 / 400
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
31.08.2011, 20:42 #13
Цитата Сообщение от AzaKendler Посмотреть сообщение
ну и если честно и объективно, если std::string например часто проходит по тексту, разве не правильней его вынести в using?
просто я как новичок могу подумать что так и надо делать всегда полные объявления
слишком много using std::* придется писать, лучше уж локально прописать
C++
1
2
3
4
5
6
void f()
{
    using namespace std;
    string a;
    ...
}
0
Bers
Заблокирован
31.08.2011, 21:28 #14
Цитата Сообщение от ForEveR Посмотреть сообщение
Bers, проще, но не дальновидно. А что, если в файл придется выводить
Понял)

Но тогда получается, что:

1. Придётся, предварительно ручками подготавливать поток вывода, и передавать его явно в качестве параметра, что бы класс сделал свою работу. (Излишняя нагрузка на вызывающую сторону)

2. Вызывающей стороне придётся самостоятельно контролировать, корректность работы потока, передаваемого объекту класса, в качестве параметра. В частности, проверять смог ли поток успешно открыть файл, или нет, и не забывать сделать потоку close()

3. Таким образом, вместо того, что бы заложить возможность введения дополнительного функционала, вы заложили сам фунционал, работа по подготовке которого полностью ложиться на плечи вызывающей стороны (пользователя).

Лично я считаю, что если вдруг приспичило выводить результат ещё и в файл - лучше добавить специализированный метод, принимающий в качестве параметра имя файла. Метод сам откроет файл в соответствии с новой задачей: в режиме перезаписи, или ещё как то...
И сам проверит успешность всей операции.

Ведь класс для того и создаётся: с целью облегчить жизнь вызывающей стороне, избавить её от львиной части рутины, по подготовкам и проверкам.
Он должен быть максимально устойчивым к ошибкам, а следовательно - принимать извне как можно меньше параметров.

Если вдруг, в самом конце работы над большим кодом, вдруг внезапно оказалось, что все это время нужно было выводить результат в файл, а не в консоль, и надо везде переделывать код - то это уже не дефект архитектуры, это - косяк планирования.

Можно вылечить за счет добавления в зоне инициализации:
Подготовка класса к работе:

Студент.SetShowMode(Режим); //здесь можно задать так, что бы студент результат писал в файл
//метод сам подготовит поток вывода в соответствии с режимом, и проверит успешность всех операций

...

Cтудент.Show(); //Сам же вывод по прежнему без изменений. Нигде в программе править не придётся.

Добавлено через 10 минут
Цитата Сообщение от AzaKendler Посмотреть сообщение
Ну похвали уже..Я ж учу еще.
0
CyBOSSeR
Эксперт С++
2309 / 1682 / 148
Регистрация: 06.03.2009
Сообщений: 3,675
01.09.2011, 01:41 #15
Цитата Сообщение от AzaKendler Посмотреть сообщение
ну и если честно и объективно, если std::string например часто проходит по тексту, разве не правильней его вынести в using?
Нет, лучше сразу забудьте о существовании этой директивы. Даже если пространство имен очень длинновато, то лучше вместа using сделать на него alias:
C++
1
2
3
4
5
namespace fs = boost::filesystem;
 
//...
bool exists = fs::exists(fileName);
//...
1
CyBOSSeR
01.09.2011, 01:42
  #16
 Комментарий модератора 
Оффтоп вычищен. В следующий раз участие в разбирательствах "почему ТС не решит задачу самостоятельно", а уж тем более отсылка во фриланс, будет наказыватся карточками. Не хотите помочь - проходите мимо.
1
AzaKendler
01.09.2011, 08:42
  #17

Не по теме:

CyBOSSeR, спасибо. а в 2х словах можно почему так? Просто читаю Страуструпа он не ругается если using std::string использовать. Поясни почему плиз, хочу понять, а отдельную тему глупо создавать ради этого пояснения



Не по теме:

Добавлено через 3 минуты

Цитата Сообщение от AzaKendler Посмотреть сообщение
using std::iterator;
using std::multimap;
using std::make_pair;
using std::string;
using std::cout;
разве так не есть гуд? why?

0
ForEveR
В астрале
Эксперт С++
7994 / 4753 / 651
Регистрация: 24.06.2010
Сообщений: 10,547
Завершенные тесты: 3
01.09.2011, 08:46 #18
AzaKendler, Потому что не только std используется. Много namespace-ов есть. Собственно namespace и были созданы, дабы избежать колизии имен.

Добавлено через 35 секунд
Bers, Лучше вывод в поток тогда грузануть. Удобнее, логичнее.

Добавлено через 1 минуту
Цитата Сообщение от AzaKendler Посмотреть сообщение
using std::iterator;
using std::multimap;
using std::make_pair;
using std::string;
using std::cout;
разве так не есть гуд? why?
Представим, что есть большой проект. И вот в одном h файле сделали using std::string.
В другом h файле сделали using somelib::string.

Оба файла подключены в один cpp.
Что мы получим в итоге? Ошибку о том, что разрешить имя string не удается.
1
rangerx
1941 / 1550 / 478
Регистрация: 31.05.2009
Сообщений: 2,913
01.09.2011, 09:06 #19
AzaKendler, использовать using таким образом можно, но локально.
1
ForEveR
В астрале
Эксперт С++
7994 / 4753 / 651
Регистрация: 24.06.2010
Сообщений: 10,547
Завершенные тесты: 3
01.09.2011, 09:08 #20
Про string не айс пример. Возьмем либо basic_string, либо map, либо vector. Что угодно.
0
01.09.2011, 09:08
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
01.09.2011, 09:08
Привет! Вот еще темы с решениями:

виртуальные функции
Здравствуйте.Перечитал различные статьи,но не могу до конца вникнуть в смысл...

Виртуальные функции
Пожалуйста, подскажите как быть: class Circles; class Rectangs; class...

Виртуальные функции
Объясните пожалуйста зачем нужны чисто виртуальные функции?

Виртуальные функции
Разработать программу с использованием наследования классов, реализующую...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru