Форум программистов, компьютерный форум CyberForum.ru

РАБОТА С ВИРТУАЛЬНЫМИ ФУНКЦИЯМИ - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 20, средняя оценка - 4.70
sto.r.m
6 / 6 / 1
Регистрация: 20.04.2009
Сообщений: 29
13.01.2010, 22:11     РАБОТА С ВИРТУАЛЬНЫМИ ФУНКЦИЯМИ #1
Доброго времени суток, форумчани! Помогите мне, пожалуйста, с задачей, у меня просто нет этой темы, а сдать нужно обязательно
Напишите, пожалуйста, хотя бы классы в общих чертах, как использовать виртуальную функцию?

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



Заранее очень-очень-…-очень благодарю!!!
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
13.01.2010, 22:11     РАБОТА С ВИРТУАЛЬНЫМИ ФУНКЦИЯМИ
Посмотрите здесь:

проблема с виртуальными функциями C++
C++ работа с функциями , С++
Работа с функциями C++
C++ Задачка с наследованием и виртуальными функциями
Работа с функциями C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Genius Ignat
1233 / 771 / 44
Регистрация: 16.09.2009
Сообщений: 2,014
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;
 
}
//----------------------
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16834 / 5255 / 323
Регистрация: 30.03.2009
Сообщений: 14,152
Записей в блоге: 26
13.01.2010, 23:35     РАБОТА С ВИРТУАЛЬНЫМИ ФУНКЦИЯМИ #3
Genius Ignat, если твой пример отобразить на поставленную задачу, то в производных классах при описании функции f слово virtual уже не нужно. Чисто с концептуальной точки зрения с точки зрения площади поверхности функция площади не может быть переопределена даже если мы от класса, например "шар", создадим производные классы "синий шар" и "зелёный шар"

Это так, чисто ремарка
Genius Ignat
1233 / 771 / 44
Регистрация: 16.09.2009
Сообщений: 2,014
14.01.2010, 10:48     РАБОТА С ВИРТУАЛЬНЫМИ ФУНКЦИЯМИ #4
Evg, я не программлю как в учебниках учат и я этому рад, а если хочешь узнать зачем,
virtual в производных классах писать читай, что такое COM.

Добавлено через 4 минуты
Не если, я не в тему задачи, пусть кто-нибудь меня подправит.
Я просто показал основную фишку C++, между прочим sto.r.m и ее еще не знает.
ISergey
Maniac
Эксперт С++
 Аватар для ISergey
1331 / 864 / 50
Регистрация: 02.01.2009
Сообщений: 2,622
Записей в блоге: 1
14.01.2010, 11:06     РАБОТА С ВИРТУАЛЬНЫМИ ФУНКЦИЯМИ #5
virtual в производных классах писать читай, что такое COM.
неверно тебе еще немного нужно почитать книги по С++....

Не по теме:

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

Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16834 / 5255 / 323
Регистрация: 30.03.2009
Сообщений: 14,152
Записей в блоге: 26
14.01.2010, 12:22     РАБОТА С ВИРТУАЛЬНЫМИ ФУНКЦИЯМИ #6
Цитата Сообщение от Genius Ignat Посмотреть сообщение
Evg, я не программлю как в учебниках учат
Я за всю свою жизнь не читал ни одного учебника ни по Си, ни по Си++. При чём тут COM не знаю, ты жи писал пример к конкретно поставленной задаче
Genius Ignat
1233 / 771 / 44
Регистрация: 16.09.2009
Сообщений: 2,014
14.01.2010, 12:30     РАБОТА С ВИРТУАЛЬНЫМИ ФУНКЦИЯМИ #7
Evg:
только пример
показывающий как пользоваться поздним связыванием, полиморфизмом и виртуальными функциями.

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

Про причины наличия виртуальные функций в производных отвечать не буду.
Написано значит написано, тому были причины.
zim22
depict1
 Аватар для zim22
276 / 141 / 2
Регистрация: 11.07.2009
Сообщений: 606
14.01.2010, 12:41     РАБОТА С ВИРТУАЛЬНЫМИ ФУНКЦИЯМИ #8
Цитата Сообщение от Evg Посмотреть сообщение
то в производных классах при описании функции f слово virtual уже не нужно.
угу. оно не нужно. но для удобства чтения его лучше писать. чтобы долго не думать - виртуальная ли функция это или обычная.
Genius Ignat, ты забыл в базовом классе виртуальный деструктор определить.
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16834 / 5255 / 323
Регистрация: 30.03.2009
Сообщений: 14,152
Записей в блоге: 26
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];
В противном случае теряется смысл наличия виртуального деструктора (конкретно в данном примере)
zim22
depict1
 Аватар для zim22
276 / 141 / 2
Регистрация: 11.07.2009
Сообщений: 606
14.01.2010, 14:49     РАБОТА С ВИРТУАЛЬНЫМИ ФУНКЦИЯМИ #10
Цитата Сообщение от Evg Посмотреть сообщение
Сделай в данном примере в базовом классе функцию f НЕвиртуальной (и определи её). Ты увидишь, что в производных классах функция f помечена как virtual, однако все вызовы pMas[i]->f(); вызывают функцию базового класса, а не производного
логично, что будет вызываться функция базового класса. ведь вызов функции идёт через указатель на базовый класс. а раз функция НЕ виртуальная - то она и вызывается (поиск по vtable не идёт).
Genius Ignat
1233 / 771 / 44
Регистрация: 16.09.2009
Сообщений: 2,014
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
И хватит спорить, в этой книге, написано и про определения типа во время выполнения,
и про полиморфизм.
По крайней мере, лучшего объяснения, и примеров я не видел, тем более в этой книге
есть нечто большее, чем просто виртуальные функции конструкторы и деструкторы, про
которые все так усердно спорят
zim22
depict1
 Аватар для zim22
276 / 141 / 2
Регистрация: 11.07.2009
Сообщений: 606
14.01.2010, 15:00     РАБОТА С ВИРТУАЛЬНЫМИ ФУНКЦИЯМИ #12
Цитата Сообщение от Genius Ignat Посмотреть сообщение
В абстрактных классах представляющих из себя интерфейсы, не нужны конструкторы, и деструкторы
если базовый класс содержит вирт.функции, то у него должен быть виртуальный деструктор.
тело которого будет определено вне класса.
Цитата Сообщение от Genius Ignat Посмотреть сообщение
В производных деструкторы, нужны не спорю,
в производных - можно и без деструкторов обойтись. в таком случае будут вызываться деструкторы базового класса.
Genius Ignat
1233 / 771 / 44
Регистрация: 16.09.2009
Сообщений: 2,014
14.01.2010, 15:03     РАБОТА С ВИРТУАЛЬНЫМИ ФУНКЦИЯМИ #13
Жесть:
Спорить не буду, пусть каждый будет при своем мнении, ну книгу лучше почитай.
zim22
depict1
 Аватар для zim22
276 / 141 / 2
Регистрация: 11.07.2009
Сообщений: 606
14.01.2010, 15:08     РАБОТА С ВИРТУАЛЬНЫМИ ФУНКЦИЯМИ #14
Цитата Сообщение от Genius Ignat Посмотреть сообщение
Спорить не буду, пусть каждый будет при своем мнении, ну книгу лучше почитай.
такого не бывает, что все мнения - верны.
кто-то ошибается: или ты, или я. я не ошибаюсь в данном случае с вероятностью 73%

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

давай уже до правды докапываться. в чём я ошибаюсь с твоей точки зрения?
Genius Ignat
1233 / 771 / 44
Регистрация: 16.09.2009
Сообщений: 2,014
14.01.2010, 15:10     РАБОТА С ВИРТУАЛЬНЫМИ ФУНКЦИЯМИ #15
Надеюсь автор темы, её закроет.
Иначе будет бесконечный апельсин.

Добавлено через 1 минуту
Книгу скачай там узнаешь,
Если автор книги ошибается, тогда я не причём.
zim22
depict1
 Аватар для zim22
276 / 141 / 2
Регистрация: 11.07.2009
Сообщений: 606
14.01.2010, 15:17     РАБОТА С ВИРТУАЛЬНЫМИ ФУНКЦИЯМИ #16
Цитата Сообщение от Genius Ignat Посмотреть сообщение
Книгу скачай там узнаешь,
у меня нет времени читать всю книгу. на какой странице я это узнаю?
Genius Ignat
1233 / 771 / 44
Регистрация: 16.09.2009
Сообщений: 2,014
14.01.2010, 15:27     РАБОТА С ВИРТУАЛЬНЫМИ ФУНКЦИЯМИ #17
Ща поищем

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

Добавлено через 7 минут
zim22: по дружески скажи, где в опциях форума можно найти, что бы в моих ответах ставилась,
кнопка "спасибо"
zim22
depict1
 Аватар для zim22
276 / 141 / 2
Регистрация: 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; 
}
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16834 / 5255 / 323
Регистрация: 30.03.2009
Сообщений: 14,152
Записей в блоге: 26
14.01.2010, 15:31     РАБОТА С ВИРТУАЛЬНЫМИ ФУНКЦИЯМИ #19
Цитата Сообщение от zim22 Посмотреть сообщение
логично, что будет вызываться функция базового класса. ведь вызов функции идёт через указатель на базовый класс. а раз функция НЕ виртуальная - то она и вызывается (поиск по vtable не идёт).
Ты утверждал, что в проиводном классе нужно функцию описывать как виртуальную (типа, чтобы глазами лучше зацепить факт виртуальности). Я тебе показал конкретный пример, а так же объяснил, почему тебе это ВООБЩЕ ничего не даст

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

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

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

Цитата Сообщение от zim22 Посмотреть сообщение
в производных - можно и без деструкторов обойтись. в таком случае будут вызываться деструкторы базового класса.
Если ты удаляешь объект производного класса (как сделано в примере), то деструктор базового класса тоже вызовется. Независимо от того,описан он в проивзодном классе, или нет. Но это тоже чисто ремарка, поскольку указанный пример уже не является примером ООП в силу указанных ошибок
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
14.01.2010, 15:31     РАБОТА С ВИРТУАЛЬНЫМИ ФУНКЦИЯМИ
Еще ссылки по теме:

C++ Создать абстрактный базовый класс с виртуальными функциями - площадь и периметр.
Создать базовый класс список. Реализовать на базе списка стек и очередь с виртуальными функциями вставки и вытаскивания C++

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

Или воспользуйтесь поиском по форуму:
Genius Ignat
1233 / 771 / 44
Регистрация: 16.09.2009
Сообщений: 2,014
14.01.2010, 15:31     РАБОТА С ВИРТУАЛЬНЫМИ ФУНКЦИЯМИ #20
Дальше книгу почитай, от указателя ни чего не зависит.
Yandex
Объявления
14.01.2010, 15:31     РАБОТА С ВИРТУАЛЬНЫМИ ФУНКЦИЯМИ
Ответ Создать тему
Опции темы

Текущее время: 13:41. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru