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

Работа с виртуальными функциями

13.01.2010, 22:11. Показов 4033. Ответов 44
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Доброго времени суток, форумчани! Помогите мне, пожалуйста, с задачей, у меня просто нет этой темы, а сдать нужно обязательно
Напишите, пожалуйста, хотя бы классы в общих чертах, как использовать виртуальную функцию?

Вот моё задание:
Создать абстрактный базовый класс с виртуальной функцией - площадь поверхности. Создать производные классы: параллелепипед, тетраэдр, шар со своими функциями площади поверхности. Для проверки определить массив ссылок на абстрактный класс, которым присваиваются адреса различных объектов.
Площадь поверхности параллелепипеда: S=6*x*y. Площадь поверхности шара: S=4*pi*r*r. Площадь поверхности тетраэдра: S=a*a*sqrt(3).



Заранее очень-очень-…-очень благодарю!!!
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
13.01.2010, 22:11
Ответы с готовыми решениями:

Проблема с виртуальными функциями
Привет. Столкнулся с небольшой проблемой, касательно виртуальных функций. Стыдно спрашивать, ибо...

Задачка с наследованием и виртуальными функциями
Диаграмма классов на приложенном рисунке. #include <iostream> class IData { public:...

Классы с виртуальными функциями. Class Student
Создать класс Студент со свойствами: ФИО, Факультет, Курс, минималь- ная оценка по экзаменам за...

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

44
1261 / 799 / 108
Регистрация: 16.09.2009
Сообщений: 2,010
13.01.2010, 23:12 2
Раз у тебя репутация есть, значит напившись программу сам, здесь приведен только пример
показывающий как пользоваться поздним связыванием, полиморфизмом и виртуальными функциями.
Надеюсь,я вам помог.

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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#include <iostream.h>
 
 
 
//Асбтрактный класс
 
class Abstract {
private:
 
public:
    virtual void f() = 0;         //чистая вируальная функция реализуется в производных классах
 
 
 
 
};
 
//Производный от базового
class Component1 : public Abstract {
private:
 
public:
    //Реализация функции базового класса
    virtual void f(){cout<<"f is Component1\n"; }        
 
 
 
 
};
//Производный от базового
class Component2 : public Abstract {
private:
 
public:
    //Реализация функции базового класса
    virtual void f(){cout<<"f is Component2\n"; }        
 
 
 
 
};
 
//Производный от базового
class Component3: public Abstract {
private:
 
public:
    //Реализация функции базового класса
    virtual void f(){cout<<"f is Component3 \n"; }        
 
 
 
 
};
 
 
 
 
//Клиент----------------
void main(){
//Массив указателей типа абстракный класс
Abstract* pMas[3] = {NULL};
 
//Создаём компоненты выделяем динамическую память: по объекты производного типа
 Component1 *pobj1  = new  Component1;
 Component2 *pobj2  = new  Component2;
 Component3 *pobj3  = new  Component3;
//-------------------------------------
 
/*Записываем в массив указателей базового типа, адреса производных объектов(компонентов, каждый
комонент имеет свою vtbl, 
*/
pMas[0]=pobj1;  //в указатель попадает адрес динамического объекта с соответствующей его типу vtbl 
pMas[1]=pobj2;  //в указатель попадает адрес динамического объекта с соответствующей его типу vtbl 
pMas[2]=pobj3;  //в указатель попадает адрес динамического объекта с соответствующей его типу vtbl 
 
//Реализуем эффект полиморфизма: смены поведения программы в реальном времени
for(int i=0;i<3;i++)pMas[i]->f();       //вызывается функция соответствующая vtbl компнента: объекта
 
 
//-------------------------------------
//ОСвобождаем память из-под компонентов, через указатели
delete pobj1;
delete pobj2;
delete pobj3;
pobj1 = NULL;
pobj2 = NULL;
pobj3 = NULL;
 
}
//----------------------
1
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
13.01.2010, 23:35 3
Genius Ignat, если твой пример отобразить на поставленную задачу, то в производных классах при описании функции f слово virtual уже не нужно. Чисто с концептуальной точки зрения с точки зрения площади поверхности функция площади не может быть переопределена даже если мы от класса, например "шар", создадим производные классы "синий шар" и "зелёный шар"

Это так, чисто ремарка
1
1261 / 799 / 108
Регистрация: 16.09.2009
Сообщений: 2,010
14.01.2010, 10:48 4
Evg, я не программлю как в учебниках учат и я этому рад, а если хочешь узнать зачем,
virtual в производных классах писать читай, что такое COM.

Добавлено через 4 минуты
Не если, я не в тему задачи, пусть кто-нибудь меня подправит.
Я просто показал основную фишку C++, между прочим sto.r.m и ее еще не знает.
0
Maniac
Эксперт С++
1464 / 965 / 160
Регистрация: 02.01.2009
Сообщений: 2,820
Записей в блоге: 1
14.01.2010, 11:06 5
virtual в производных классах писать читай, что такое COM.
неверно тебе еще немного нужно почитать книги по С++....

Не по теме:

Раз у тебя репутация есть, значит напившись программу сам, здесь приведен только пример
Это поправимо :D

0
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
14.01.2010, 12:22 6
Цитата Сообщение от Genius Ignat Посмотреть сообщение
Evg, я не программлю как в учебниках учат
Я за всю свою жизнь не читал ни одного учебника ни по Си, ни по Си++. При чём тут COM не знаю, ты жи писал пример к конкретно поставленной задаче
0
1261 / 799 / 108
Регистрация: 16.09.2009
Сообщений: 2,010
14.01.2010, 12:30 7
Evg:
только пример
показывающий как пользоваться поздним связыванием, полиморфизмом и виртуальными функциями.

Моя цель была, показать синтаксис, а не решать задачу.
Evg: Если хочешь напиши сам, поставленную задачу, если тебе не нравится virtual в производных
убирай, мне все равно.

Про причины наличия виртуальные функций в производных отвечать не буду.
Написано значит написано, тому были причины.
0
depict1
281 / 146 / 4
Регистрация: 11.07.2009
Сообщений: 606
14.01.2010, 12:41 8
Цитата Сообщение от Evg Посмотреть сообщение
то в производных классах при описании функции f слово virtual уже не нужно.
угу. оно не нужно. но для удобства чтения его лучше писать. чтобы долго не думать - виртуальная ли функция это или обычная.
Genius Ignat, ты забыл в базовом классе виртуальный деструктор определить.
0
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
14.01.2010, 14:35 9
Цитата Сообщение от zim22 Посмотреть сообщение
угу. оно не нужно. но для удобства чтения его лучше писать. чтобы долго не думать - виртуальная ли функция это или обычная.
Тебе это не даёт ровным счётом ничего, потому как ты не знаешь, виртуальная функция была в базовом классе, или нет (т.е. виртуальность начинается на уровне нашего класса или началась где-то выше по иерархии классов). Сделай в данном примере в базовом классе функцию f НЕвиртуальной (и определи её). Ты увидишь, что в производных классах функция f помечена как virtual, однако все вызовы pMas[i]->f(); вызывают функцию базового класса, а не производного

Цитата Сообщение от zim22 Посмотреть сообщение
Genius Ignat, ты забыл в базовом классе виртуальный деструктор определить.
В этом случае надо менять код

C++
1
2
3
delete pobj1;
delete pobj2;
delete pobj3;
на

C++
1
2
3
delete pMas[0];
delete pMas[1];
delete pMas[2];
В противном случае теряется смысл наличия виртуального деструктора (конкретно в данном примере)
0
depict1
281 / 146 / 4
Регистрация: 11.07.2009
Сообщений: 606
14.01.2010, 14:49 10
Цитата Сообщение от Evg Посмотреть сообщение
Сделай в данном примере в базовом классе функцию f НЕвиртуальной (и определи её). Ты увидишь, что в производных классах функция f помечена как virtual, однако все вызовы pMas[i]->f(); вызывают функцию базового класса, а не производного
логично, что будет вызываться функция базового класса. ведь вызов функции идёт через указатель на базовый класс. а раз функция НЕ виртуальная - то она и вызывается (поиск по vtable не идёт).
0
1261 / 799 / 108
Регистрация: 16.09.2009
Сообщений: 2,010
14.01.2010, 14:56 11
zim22:
В абстрактных классах представляющих из себя интерфейсы, не нужны конструкторы, и деструкторы
В производных деструкторы, нужны не спорю, ну забыл приписать, ты посмотри на время, когда
был пост с примером: спать хотелось.

исправлюсь:

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
//Производный от базового
class Component1 : public Abstract {
private:
 
public:
        Component3(){}
        virtual~Component3(){}
 
        //Реализация функции базового класса
        virtual void f(){cout<<"f is Component1\n"; }        
 
};
//Производный от базового
class Component2 : public Abstract {
private:
 
public:
 
        Component2(){}
        virtual~Component2(){}  //Реализация функции базового класса
        virtual void f(){cout<<"f is Component2\n"; }        
 
};
 
//Производный от базового
class Component3: public Abstract {
private:
 
public:
Component3(){}
virtual~Component3(){}
        //Реализация функции базового класса
        virtual void f(){cout<<"f is Component3 \n"; }        
 };
Добавлено через 6 минут
Почитайте лучше:
http://it-books.narod.ru/COM/InsideCOM_rus.rar
И хватит спорить, в этой книге, написано и про определения типа во время выполнения,
и про полиморфизм.
По крайней мере, лучшего объяснения, и примеров я не видел, тем более в этой книге
есть нечто большее, чем просто виртуальные функции конструкторы и деструкторы, про
которые все так усердно спорят
0
depict1
281 / 146 / 4
Регистрация: 11.07.2009
Сообщений: 606
14.01.2010, 15:00 12
Цитата Сообщение от Genius Ignat Посмотреть сообщение
В абстрактных классах представляющих из себя интерфейсы, не нужны конструкторы, и деструкторы
если базовый класс содержит вирт.функции, то у него должен быть виртуальный деструктор.
тело которого будет определено вне класса.
Цитата Сообщение от Genius Ignat Посмотреть сообщение
В производных деструкторы, нужны не спорю,
в производных - можно и без деструкторов обойтись. в таком случае будут вызываться деструкторы базового класса.
0
1261 / 799 / 108
Регистрация: 16.09.2009
Сообщений: 2,010
14.01.2010, 15:03 13
Жесть:
Спорить не буду, пусть каждый будет при своем мнении, ну книгу лучше почитай.
0
depict1
281 / 146 / 4
Регистрация: 11.07.2009
Сообщений: 606
14.01.2010, 15:08 14
Цитата Сообщение от Genius Ignat Посмотреть сообщение
Спорить не буду, пусть каждый будет при своем мнении, ну книгу лучше почитай.
такого не бывает, что все мнения - верны.
кто-то ошибается: или ты, или я. я не ошибаюсь в данном случае с вероятностью 73%

у меня на винте список из порядка 100 книг валяется по С++/алгоритмам/т.д.
так мне что тоже говорить тебе, чтобы ты их все прочитал?

давай уже до правды докапываться. в чём я ошибаюсь с твоей точки зрения?
0
1261 / 799 / 108
Регистрация: 16.09.2009
Сообщений: 2,010
14.01.2010, 15:10 15
Надеюсь автор темы, её закроет.
Иначе будет бесконечный апельсин.

Добавлено через 1 минуту
Книгу скачай там узнаешь,
Если автор книги ошибается, тогда я не причём.
0
depict1
281 / 146 / 4
Регистрация: 11.07.2009
Сообщений: 606
14.01.2010, 15:17 16
Цитата Сообщение от Genius Ignat Посмотреть сообщение
Книгу скачай там узнаешь,
у меня нет времени читать всю книгу. на какой странице я это узнаю?
0
1261 / 799 / 108
Регистрация: 16.09.2009
Сообщений: 2,010
14.01.2010, 15:27 17
Ща поищем

Добавлено через 1 минуту
стр.27

Добавлено через 7 минут
zim22: по дружески скажи, где в опциях форума можно найти, что бы в моих ответах ставилась,
кнопка "спасибо"
0
depict1
281 / 146 / 4
Регистрация: 11.07.2009
Сообщений: 606
14.01.2010, 15:29 18
Цитата Сообщение от Genius Ignat Посмотреть сообщение
Ща поищем
стр.27
в примере в книге не был определён виртуальный деструктор в базовых классах-интерфейсах потому-что удаление объекта класса CA велось напрямую, а не через указатель на его базовый класс.
***
вот сорс-код из книги
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
#define interface struct
#include <iostream.h> 
#include <objbase.h>   // Определить интерфейс 
 
void trace(const char* pMsg) { cout << pMsg << endl; } 
 
// Абстрактные интерфейсы 
interface IX 
{ 
  virtual void __stdcall Fx1() = 0; 
  virtual void __stdcall Fx2() = 0; 
}; 
 
interface IY 
{ 
  virtual void __stdcall Fy1() = 0; 
  virtual void __stdcall Fy2() = 0; 
}; 
 
// Реализация интерфейса 
class CA : public IX,  
           public IY 
{ 
public: 
 
 // Реализация интерфейса IX 
  virtual void __stdcall Fx1() { cout << "CA::Fx1" << endl; } 
  virtual void __stdcall Fx2() { cout << "CA::Fx2" << endl; } 
 
 // Реализация интерфейса IY 
  virtual void __stdcall Fy1() { cout << "CA::Fy1" << endl; } 
  virtual void __stdcall Fy2() { cout << "CA::Fy2" << endl; } 
 
}; 
 
 
// Клиент 
int main() 
{ 
 trace("Клиент: Создание экземпляра компонента"); 
  CA* pA = new CA; 
 
  // Получить указатель IX 
  IX* pIX = pA; 
 
 trace("Клиент: Использование интерфейса IX"); 
 pIX->Fx1(); 
 pIX->Fx2(); 
 
  // Получить указатель IY 
  IY* pIY = pA; 
 
 trace("Клиент: Использование интерфейса IY"); 
 pIY->Fy1(); 
 pIY->Fy2(); 
 
 trace("Клиент: Удаление компонента"); 
 delete pA; 
 
 return 0; 
}
0
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
14.01.2010, 15:31 19
Цитата Сообщение от zim22 Посмотреть сообщение
логично, что будет вызываться функция базового класса. ведь вызов функции идёт через указатель на базовый класс. а раз функция НЕ виртуальная - то она и вызывается (поиск по vtable не идёт).
Ты утверждал, что в проиводном классе нужно функцию описывать как виртуальную (типа, чтобы глазами лучше зацепить факт виртуальности). Я тебе показал конкретный пример, а так же объяснил, почему тебе это ВООБЩЕ ничего не даст

Цитата Сообщение от Genius Ignat Посмотреть сообщение
В абстрактных классах представляющих из себя интерфейсы, не нужны конструкторы, и деструкторы
В производных деструкторы, нужны не спорю
Если ты пишешь деструкторы в производных классоах (но асбтрактный оставляешь без деструктора), то удалять (delete) объекты производного класса можно только через указатель производного класса. А вот если ты в базовом классе опишешь деструктор, что ты сможешь удалять объект через указатель на базовый класс. В этом-то и есть весь прикол. Производный класс тебе нужен только в момент создания объекта, после чего ты указатель на производный класс преобразуешь в указатель на базовый класс и вообще напрочь забываешь про проивзодный класс. В этом и есть мощь механизма виртуальных функций (а так же ООП, о чём говорилось в одной из соседних тем).

Цитата Сообщение от Genius Ignat Посмотреть сообщение
Почитайте лучше:
http://it-books.narod.ru/COM/InsideCOM_rus.rar
И хватит спорить, в этой книге, написано и про определения типа во время выполнения,
и про полиморфизм.
По крайней мере, лучшего объяснения, и примеров я не видел, тем более в этой книге
есть нечто большее, чем просто виртуальные функции конструкторы и деструкторы, про
которые все так усердно спорят
Зачем отсылать людей к какой-то книге. Тебе конкретно в твоём примере показали недочёты, которые уже сами по себе говорят о том, что тебе не мешало бы почитать про ООП (не путать с "прочитать учебник по Си++")

Цитата Сообщение от zim22 Посмотреть сообщение
если базовый класс содержит вирт.функции, то у него должен быть виртуальный деструктор.
тело которого будет определено вне класса.
Необязательно. Правда в этом случае будет "программирование через классы", а не "ООП". Тело виртуального деструктора необязательно определать вне класса (т.е. на вскидку я не вижу ни одной причины, почему должно быть иначе)

Цитата Сообщение от zim22 Посмотреть сообщение
в производных - можно и без деструкторов обойтись. в таком случае будут вызываться деструкторы базового класса.
Если ты удаляешь объект производного класса (как сделано в примере), то деструктор базового класса тоже вызовется. Независимо от того,описан он в проивзодном классе, или нет. Но это тоже чисто ремарка, поскольку указанный пример уже не является примером ООП в силу указанных ошибок
0
1261 / 799 / 108
Регистрация: 16.09.2009
Сообщений: 2,010
14.01.2010, 15:31 20
Дальше книгу почитай, от указателя ни чего не зависит.
0
14.01.2010, 15:31
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
14.01.2010, 15:31
Помогаю со студенческими работами здесь

Реализовать абстрактный класс pair c виртуальными арифметическими функциями
Вот задание: Создать абстрактный базовый класс Pair с виртуальными арифметическими операциями....

Создать абстрактный базовый класс с виртуальными функциями - площадь и периметр
Помогите написать,не врублюсь как писать много пропустил (( Задание:Создать абстрактный базовый...

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

Создать абстрактный базовый класс Тройка чисел с виртуальными методами увеличения на 1. Создать производный класс Время со своими функциями
Здравствуйте, пожалуйста помогите написать код к данной задаче, с таким условием: Создать...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru