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

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

21.04.2014, 18:59. Просмотров 462. Ответов 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() {}; // Деструктор    
};


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

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

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

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

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

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

3
nmcf
6237 / 5549 / 2524
Регистрация: 14.04.2014
Сообщений: 23,337
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
:)
Эксперт С++
4746 / 3240 / 496
Регистрация: 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