Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.86/21: Рейтинг темы: голосов - 21, средняя оценка - 4.86
0 / 0 / 1
Регистрация: 18.12.2012
Сообщений: 11

Виртуальные функции (создать массив указателей на объекты трех классов)

18.12.2012, 10:32. Показов 4292. Ответов 14
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Задание: создать массив указателей на объекты трех классов. Метод Show почему-то не переопределяется. В данном коде вводится 3 элемента в массив: Имя-Группа, Имя-Группа-4 оценки, Имя-Группа-4 оценки-4 оценки.

Student.h
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
#include <iostream>
 
using namespace std;
 
class Student
{
protected:
    char *Name;
    int Group;
public: 
    Student () 
    {
        Name = NULL;
        Group = 0;
    }
    Student (int x, char *y)
    {
        Group = x;
        Name = y;
    }
    ~Student(){};
    virtual void Show()
    {
        cout << "Name: " << Name << endl << "Group: " << Group << endl;
    }
};
Student1.h
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
#include "Student.h"
class Student1:public Student 
{
protected:
    int marks1[4];
public:
    Student1 (): Student ()
    {
        for (int i=0; i<4; i++)
        {
            marks1[i]=0;
        }
    }
    Student1 (int x, char *y, int m1[4]):Student (x,y)
    {
        for (int i=0; i<4; i++)
        {
            marks1[i]=m1[i];
        }
    }
    ~Student1 () {};
    void Show() 
    {
        Student::Show();
        double ave = this->average();
        cout << "Marks: ";
        for(int i=0; i<4; i++)
        {
            cout << marks1[i] << " ";
        }
        cout << endl;
        cout << "The average: " << ave << endl; 
    }
    virtual double average()
    {
        double ave=0;
        for (int i=0; i<4; i++)
        ave += marks1[i];
        return ave/4;
    }
};
Student2.h
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
include "Student1.h"
 
class Student2: public Student1
{
protected:
    int marks2[4];
public:
    Student2 (): Student1 ()
    {
        for (int i=0; i<4; i++)
        {
            marks2[i]=0;
        }
    }
    Student2 (int x, char *y, int m1[4], int m2[4]): Student1 (x, y, m1)
    {
        for (int i=0; i<4; i++)
        {
            marks2[i]=m2[i];
        }
    }
    ~Student2 () {};
    void Show();
    double average();
};
 
void Student2::Show()
{
    double ave=this->average();
    cout << "Marks: ";
    for(int i=0;i<4;i++)
    {
        cout << marks1[i] << " ";
    }
    for(int i=0;i<4;i++)
    {
        cout << marks2[i] << " ";
    }
    cout << endl;
    cout << "The average: " << ave << endl; 
}
 
double Student2::average()
{
    double ave=0;
    for (int i=0;i<4;i++)
    ave += (marks1[i] + marks2[i]);
    return ave/8;
}
main.cpp
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
#include "Student2.h"
#include <conio.h>
void main ()
{
    Student *mass[3];
    for (int i=0; i<2; i++)
    {
        char name[20];
        int group, mark1[4], mark2[4];
        cout << "Vvedite informaciu o treh studentah (Imia, gruppa; Imia, gruppa, ocenki; Imia, gruppa, ocenki, ocenki.)" << endl;
        cin >> name >> group;
        mass[i++] = &Student (group, name);
        cin >> name >> group;
        for (int a=0; a<4; a++)
        {
            cin >> mark1[a];
        }
        mass[i++] = &Student1 (group, name, mark1);
        cin >> name >> group;
        for (int b=0; b<4; b++)
        {
            cin >> mark1[b];
        }
        for (int c=0; c<4; c++)
        {
            cin >> mark2[c];
        }
        mass[i] = &Student2 (group, name, mark1, mark2);
    }
    for (int i=0; i<3; i++)
    {
        mass[i]->Show();
    }
 
 
    getch();
}
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
18.12.2012, 10:32
Ответы с готовыми решениями:

Как понять: массив указателей на объекты классов?
если приведете пример буду рад.

Абстрактный класс, массив указателей на объекты производных классов
У меня есть абстрактный класс: class abstract{ public: int field; double method(); }; В нем объявлены поле и метод. Далее...

Как создать массив указателей на объекты
Задача состоит в создании многофайлового проекта. Каждый класс находится в отдельном файле. В файле main.cpp нужно создать массив...

14
 Аватар для Schizorb
512 / 464 / 81
Регистрация: 07.04.2012
Сообщений: 869
Записей в блоге: 1
18.12.2012, 11:13
C++
1
mass[i++] = &Student (group, name);
Так разве можно? У меня компилятор ругается на взятие адреса временного объекта.


C++
1
mass[i++] = new Student (group, name);
0
ComfyMobile
 Аватар для Nixy
401 / 282 / 34
Регистрация: 24.07.2012
Сообщений: 916
18.12.2012, 11:32
помимо этого у вас инициализация в цикл зачем то помещена и первый объект класса Student имеет индекс 1, воторой имеет индекс 2, и третий тоже 2

Добавлено через 11 минут
C++
1
2
3
4
5
 Student (int x, char *y)
    {
        Group = x;
        Name = y;
    }
из за такой инициализации у вас каждый раз новый объект будет указывать на один и тотже источник char ов , и последний вариант будет и первым и вторым

Добавлено через 5 минут
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
void main ()
{
    Student *mass[3];
 
 
        char* name = new char[20];
        int group, mark1[4], mark2[4];
        cout << "Vvedite informaciu o treh studentah (Imia, gruppa; Imia, gruppa, ocenki; Imia, gruppa, ocenki, ocenki.)" << endl;
        cin >> name >> group;
        mass[0] = new Student (group, name);
        name = new char[20];
        cin >> name >> group;
        for (int a=0; a<4; a++)
        {
            cin >> mark1[a];
        }
        mass[1] = new Student1 (group, name, mark1);
        cin >> name >> group;
        name = new char[20];
        for (int b=0; b<4; b++)
        {
            cin >> mark1[b];
        }
        for (int c=0; c<4; c++)
        {
            cin >> mark2[c];
        }
        mass[2] = new Student2 (group, name, mark1, mark2);
 
    for ( int i=0; i<3; i++)
    {
        mass[i]->Show();
    }
 
 
    getch();
}
и
C++
1
2
3
4
5
void Student2::Show() {
 
    Student::Show();
...
}
0
0 / 0 / 1
Регистрация: 18.12.2012
Сообщений: 11
18.12.2012, 12:34  [ТС]
В том-то и дело, что цикл задан правильно. Но при попытке вывода показывает только имя и группу (верные имя и группу, соответствующие ожидаемым). Мне надо, чтобы функция для наследника выводила еще оценки и средний балл.
0
ComfyMobile
 Аватар для Nixy
401 / 282 / 34
Регистрация: 24.07.2012
Сообщений: 916
18.12.2012, 12:39
Цитата Сообщение от absurd_logik Посмотреть сообщение
В том-то и дело, что цикл задан правильно. Но при попытке вывода показывает только имя и группу (верные имя и группу, соответствующие ожидаемым). Мне надо, чтобы функция для наследника выводила еще оценки и средний балл.
цикл ошибочный,и я объяснил почему, возьмите мой код функции main
0
0 / 0 / 1
Регистрация: 18.12.2012
Сообщений: 11
18.12.2012, 12:43  [ТС]
Цитата Сообщение от Schizorb Посмотреть сообщение
C++
1
mass[i++] = &Student (group, name);
Так разве можно? У меня компилятор ругается на взятие адреса временного объекта.


C++
1
mass[i++] = new Student (group, name);
У меня не ругается. У вас visual studio?

Добавлено через 2 минуты
Цитата Сообщение от Nixy Посмотреть сообщение
цикл ошибочный,и я объяснил почему, возьмите мой код функции main
Вы путаете [i++] и [++i].
0
 Аватар для Schizorb
512 / 464 / 81
Регистрация: 07.04.2012
Сообщений: 869
Записей в блоге: 1
18.12.2012, 12:53
Цитата Сообщение от absurd_logik Посмотреть сообщение
У вас visual studio
нет, у меня gcc. И выводит прога для каждого класса свои данные, как я понял.

Code
1
2
3
4
5
6
7
8
Name: Sidorov
Group: 23
Name: Sidorov
Group: 22
Marks: 2 3 4 4
The average: 3.25
Marks: 4 5 6 3 5 4 3 3
The average: 4.125
Только name у всех совпадает, вам уже написал почему.
0
0 / 0 / 1
Регистрация: 18.12.2012
Сообщений: 11
18.12.2012, 13:00  [ТС]
Цитата Сообщение от Schizorb Посмотреть сообщение
нет, у меня gcc. И выводит прога для каждого класса свои данные, как я понял.

Только name у всех совпадает, вам уже написал почему.
name у всех разное. Но кажется я начинаю понимать, как это сделать.

Добавлено через 3 минуты
Нет, все же не понимаю. У меня выводит разные(!) имена и группы, но оценки не выводятся вообще. Именно в них и проблема.
0
ComfyMobile
 Аватар для Nixy
401 / 282 / 34
Регистрация: 24.07.2012
Сообщений: 916
18.12.2012, 13:14
Цитата Сообщение от absurd_logik Посмотреть сообщение
Вы путаете [i++] и [++i].
это вы ошибаетесь если думаете что это разные веши, очень страно что у вас разные имена, так как указателя на начало массива char у вас 1 для всех, не важно какой компилятор при вашем вызове у вас сразу вызывается деструктор объектов,подебажте
0
 Аватар для Schizorb
512 / 464 / 81
Регистрация: 07.04.2012
Сообщений: 869
Записей в блоге: 1
18.12.2012, 13:16
absurd_logik, вариант с динамическим выделением памяти с помощью new попробовали? результаты те же?
0
0 / 0 / 1
Регистрация: 18.12.2012
Сообщений: 11
18.12.2012, 13:28  [ТС]
Schizorb, да. Выделял каждому указателю память под нужный класс. Но бесполезно. Вне массива метод работает, это я тоже проверял.

Добавлено через 3 минуты
Schizorb, да. Выделял каждому указателю память под нужный класс. Но бесполезно. Вне массива метод работает, это я тоже проверял.
Nixy, это разные вещи. ++i сперва увеличит число, а потом его использует, а i++ наоборот.

Добавлено через 2 минуты
Да и как же сразу вызывается деструктор, если программа работает?
0
 Аватар для taras atavin
4226 / 1796 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
18.12.2012, 13:39
Цитата Сообщение от absurd_logik Посмотреть сообщение
Метод Show почему-то не переопределяется.
Мне казалось, что при перекрытии виртуального метода надо продублировать его прототип/заголовок в потомке.
0
0 / 0 / 1
Регистрация: 18.12.2012
Сообщений: 11
18.12.2012, 13:55  [ТС]
Цитата Сообщение от taras atavin Посмотреть сообщение
Мне казалось, что при перекрытии виртуального метода надо продублировать его прототип/заголовок в потомке.
Не уверен. В любом случае я это уже добавил в код.

Добавлено через 2 минуты
Цитата Сообщение от taras atavin Посмотреть сообщение
Мне казалось, что при перекрытии виртуального метода надо продублировать его прототип/заголовок в потомке.
Погодите, так я же их переопределил. Я вас неправильно понял. Виртуальные методы наследуются.
0
ComfyMobile
 Аватар для Nixy
401 / 282 / 34
Регистрация: 24.07.2012
Сообщений: 916
18.12.2012, 14:12
с моим коддом все работает, вы хоть пробовали дебагом пользоватся , или не понимаете о чем я?
почти правильно надо в последнем случае поменять местами строки 19 и 18 местами
Миниатюры
Виртуальные функции (создать массив указателей на объекты трех классов)  
0
 Аватар для taras atavin
4226 / 1796 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
18.12.2012, 14:15
Цитата Сообщение от absurd_logik Посмотреть сообщение
Виртуальные методы наследуются.
Наследуется метод предка, при переопределении создаётся метод потомка с той же сигнатурой. Как он может наследоваться?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
18.12.2012, 14:15
Помогаю со студенческими работами здесь

Создать массив указателей на объекты класса, описывающего насекомых
Создать массив указателей на объекты класса, описывающего насекомых (количество ног, наличие крыльев, цвет, название.). Создать новый...

Создать специфицированный шаблон функции, принимающей массив указателей на char и количество самих указателей
Задача: создать специфицированный шаблон функции, принимающей массив указателей на char и количество самих указателей. Вернуть адрес...

Почему в сортировке указателей на объекты в вызове функции используются адреса объектов, а не указателей?
Доброго времени суток! Рассматриваю пример (из Лафоре) сортировки массива указателей на объекты, для чего используются указатели на...

Как создать класс контейнер-динамический массив и поместить туда объекты других классов?
Какой тип массива использовать тип базового класса или наследников?

Различные функции, для которых можно создать массив указателей на функции
Придумайте не менее 3-х различных функций, для которых можно создать массив указателей на функции.


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

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
SDL3 для Android: Загрузка PNG с альфа-каналом с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru