Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.80/5: Рейтинг темы: голосов - 5, средняя оценка - 4.80
Skedaddler
1 / 1 / 2
Регистрация: 24.02.2014
Сообщений: 13
#1

Виртуальные функции в классах - нужен пример

21.04.2014, 18:59. Просмотров 968. Ответов 3
Метки нет (Все метки)

Добрый день. Хочу сразу извиниться за столь простые вопросы (виртуальные функции считаются азами ООП). Однако я никак не могу вникнуть в виртаульные функции: и читал Страуструпа, и искал в интернете - понятнее не стало.
Был бы очень благодарен, если кто-нибудь напишет понятным языком что такое виртаульные функции и с чем их едят на моем примере.
Есть класс рациональных чисел:
Кликните здесь для просмотра всего текста

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
#ifndef RATIO_H
#define RATIO_H
#include <iostream>
using namespace std;
 
class Ratio
{   
    int num; // Числитель (numerator)
    int den; // Знаменатель (denominator)
public:
    Ratio() // Конструктор по умолчанию
    {num = 0; 
    den = 1;}
    explicit Ratio (int n, int d) : num(n), den(d) // Конструктор параметрами 
    {if (den == 0) 
    cout << "Error: знаменатель не можеть равняться нулю!\n";} 
    Ratio (const Ratio &src) : num(src.num), den(src.den) {} // Конструктор копирования
 
    /* Перегрузка операторов */
    Ratio operator* (const Ratio &x) const; // Оператор умножения дробей
    Ratio operator/ (const Ratio &x) const; // Оператор деления дробей
    Ratio& operator= (const Ratio &src); // Оператор присваивания
    Ratio& operator*= (const Ratio &x); // Оператор присваивания с умножением
    Ratio& operator/= (const Ratio &x); // Оператор присваивания с делением
    friend ostream& operator<< (ostream& outs, const Ratio &x); // Перегрузка ввода
    friend istream& operator>> (istream& ins, Ratio &x);  // Перегрузка вывода
    bool operator== (const Ratio &x) const; // Оператор эквивалентности
    bool operator!= (const Ratio &x) const; // Оператор не тождественности
    operator int() const; // Представление дроби как целого числа
    operator double() const; // Представление дроби как числа с плавающей запятой
    
    /* Методы */
    virtual void invert (); // Меняет местами числитель и знаменатель
    virtual void reduce (); // Сокращает дробь
    virtual int gcd (); // Находит наибольший общий делитель
    virtual ~Ratio() {}; // Деструктор  
};
 
#endif


Далее есть класс именованных дробей (то есть у каждое дроби будет какое-то имя). Этот класс является наследуемым у класса рациональных чисел.
Кликните здесь для просмотра всего текста

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
#include <iostream>
#include <stdlib.h>
#include <cstring> // Для работы с именем дроби
#include "Ratio.h" // Заголовочный файл с классом
 
class Named_Ratio: public Ratio // Класс именованных дробей
{
    string name; // Имя дроби
public:
    Named_Ratio (int n = 0, int d = 1, string na = "Default") : Ratio(n, d), name(na) {} // Конструктор по умолчанию с параметрами
    Named_Ratio (const Named_Ratio &src) : Ratio(src), name (src.name) {} // Конструктор копирования
 
    /* Перегрузка операторов */
    Named_Ratio operator* (const Named_Ratio &x) const; // Оператор умножения дробей
    Named_Ratio operator/ (const Named_Ratio &x) const; // Оператор деления дробей
    Named_Ratio& operator= (const Named_Ratio &src); // Оператор присваивания
    Named_Ratio& operator*= (const Named_Ratio &x); // Оператор присваивания с умножением
    Named_Ratio& operator/= (const Named_Ratio &x); // Оператор присваивания с делением
    friend ostream& operator<< (ostream& outs, const Named_Ratio &x); // Перегрузка ввода
    friend istream& operator>> (istream& ins, Named_Ratio &x);  // Перегрузка вывода
    bool operator== (const Named_Ratio &x) const; // Оператор эквивалентности
    bool operator!= (const Named_Ratio &x) const; // Оператор не тождественности
    operator int() const; // Представление дроби как целого числа
    operator double() const; // Предстаавление дроби как числа с плавающей запятой
 
    /* Методы */
    void invert (); // Меняет местами числитель и знаменатель
    void reduce (); // Сокращает дробь
    int gcd (); // Находит наибольший общий делитель
    ~Named_Ratio() {}; // Деструктор    
};


Вот моя логика (как я понял суть виртуальных функций): у меня есть методы в классе рациональных чисел (сокращение, поиск НОД, инвертирование). В классе именованных дробей они понадобятся мне только для чисел, а не для имени, поэтому я их оставляю без изменения, поэтому надо обращаться в базовый класс, соответственно они виртуальны. Так?
Деструктор виртаульный так как это является признаком хорошего тона и вроде как придется через указатель вызывать деструктор дочернего класса.
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
21.04.2014, 18:59
Ответы с готовыми решениями:

Виртуальные функции (нужно ли во всех производных классах писать слово virtual?)
Нужно ли во всех производных классах писать слово virtual? Или достаточно...

Нужен пример функции для работы со строками
Какие функции для работы со строками есть. Если не сложно можете привести пример

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

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

Нужен пример перехвата API функции на Detours!!!
В долгих поисках пришел к выводу использовать Detours для отлова пакетов. Где...

3
nmcf
6271 / 5577 / 2537
Регистрация: 14.04.2014
Сообщений: 23,468
21.04.2014, 19:28 #2
Прототип один, а содержимое у каждого класса может быть своё.
0
Skedaddler
1 / 1 / 2
Регистрация: 24.02.2014
Сообщений: 13
21.04.2014, 19:40  [ТС] #3
nmcf, а если мне в классе именованных дробей не нужно другое содержание? То есть эти функции и в дочернем классе зависят только от переменных num и den.
И если не трудно, не могли бы вы своими сломи дать определение виртуальной функции?
0
Tulosba
:)
Эксперт С++
4747 / 3241 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
21.04.2014, 20:06 #4
Лучший ответ Сообщение было отмечено Skedaddler как решение

Решение

Skedaddler, если в дочернем классе тело функции должно быть таким же как в базовом и это условие сохраняется для всей иерархии классов, то функцию нет смысла делать виртуальной.
Для виртуальных функций вызываемый код определяется в момент выполнения, для невиртуальных - в момент компиляции. Если, скажем, есть указатель на объект базового класса, который в процессе выполнения может указывать на объекты разных уровней иерархии, то для виртуальной функции будет вызываться код, связанный с тем типом объекта, на который в текущий момент указывает указатель, а для обычной функции будет вызываться код, связанный с базовым классом.
1
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
21.04.2014, 20:06

Нужен простой пример передачи одной функции или метода в другую функцию или метод
Собственно сабж. Не знаю, как сделать. Как это выглядит синтаксически? Пробовал...

Нужен typedef в нескольких классах
Как пользоваться typedef в данном случаи? 1) В каждом классе писать typedef?...

функции в классах
есть класс my_class, у него есть две функцииmy_class::X_definition(int k, long...


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

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

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