Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.73/15: Рейтинг темы: голосов - 15, средняя оценка - 4.73
11 / 1 / 1
Регистрация: 02.10.2015
Сообщений: 98
1

Виртуальный абстрактный класс

23.12.2016, 15:43. Просмотров 2933. Ответов 14
Метки нет (Все метки)


Надеюсь мой вопрос будет не глупым. Есть класс исключений в пространстве имен std
У него есть метод what
Я создаю свой базовый класс исключений, абстрактный.
В нем переопределяю функцию what.

C++
1
2
3
4
5
6
7
8
    class cError: public std::exception{
            public:
                virtual ~cErrorCan(){}
                                virtual const char* what( void ) const { return sError_.c_str(); } // Этот метод общий должен быть для всех подклассов
            protected:
                std::string sError_;
                cError();
        };
Потом конкретные классы исключений наследую от него. Вопрос. В таком случае получается класс чью реализацию они унаследуют?
Тут нужно наследовать виртуально?
C++
1
class cError:virtual public std::exception{
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
23.12.2016, 15:43
Ответы с готовыми решениями:

Виртуальный методы, абстрактный класс.
Здравствуйте. Теоретические вопросы. Что такое виртуальный методы и что такое абстрактный класс....

Абстрактный класс. Виртуальный метод, который возвращает T- тип
Привет! Допустим, есть абстрактный класс, и метод, который возвращает T-тип. class A {...

Абстрактный класс «Клиент банка», имеющий виртуальный метод для вывода данных о клиенте
Создать абстрактный класс «Клиент банка», имеющий поля ФИО и адрес, а также метод, для вывода...

Класс: Разработать абстрактный класс класс Point для задания координаты...
Всем привет, помогите пожалуйста решить задачу, я уже всю голову сломал, не знаю как решить... ...

__________________
Помогаю в написании курсовых работ и дипломов здесь.
Записывайтесь на профессиональные курсы C++ разработчиков
14
Форумчанин
Эксперт CЭксперт С++
8164 / 5012 / 1436
Регистрация: 29.11.2010
Сообщений: 13,455
23.12.2016, 15:48 2
Цитата Сообщение от Oryel Посмотреть сообщение
абстрактный.
Он не абстрактный, у него нет чисто виртуальных функций.
Цитата Сообщение от Oryel Посмотреть сообщение
Тут нужно наследовать виртуально?
Зачем? Виртуальное наследование нужно только для решения проблемы с ромбом при множественном наследовании.
0
Эксперт С++
8411 / 3946 / 864
Регистрация: 15.11.2014
Сообщений: 8,894
23.12.2016, 15:48 3
Цитата Сообщение от Oryel Посмотреть сообщение
В таком случае получается класс чью реализацию они унаследуют?
огаа.
Цитата Сообщение от Oryel Посмотреть сообщение
Тут нужно наследовать виртуально?
нит.
0
Форумчанин
Эксперт CЭксперт С++
8164 / 5012 / 1436
Регистрация: 29.11.2010
Сообщений: 13,455
23.12.2016, 15:52 4
Можно, кстати, добавить реализацию чисто виртуальной функции как вариант по умолчанию.
То есть мы будем требовать явного переопределения виртуальной функции (чтобы создать объект не абстрактного класса), но при этом наследники могут внутри метода вызывать реализацию для этой функции базового класса.
0
11 / 1 / 1
Регистрация: 02.10.2015
Сообщений: 98
23.12.2016, 15:57  [ТС] 5
дык.....
Абстрактный класс в объектно-ориентированном программировании — базовый класс, который не предполагает создания экземпляров
Достаточно просто конструктор кинуть в протектед. Если я не прав давай пруф, аналогично, к своему ответу требую пруф, что это не абстрактный класс.

Это вопрос с абстрактностью думаю закрыт. Отсылаю вас в гугл и в книги( тотже Страусттруп)

Вопрос у меня звучал так. std::exception - вроде не абстрактный класс. У него своя реализация метода what, я так думаю. Я унаследовал его в доругом классе. Потом еще в одном. Какую реализацию вызовет наследник?? И почему?

Даже если уйти от конкретного случая... есть класс, наследую его, переопределяю метотд. Наследую этот новый класс. Чья реализация метода вывозиться от наследника этих классов?
0
Форумчанин
Эксперт CЭксперт С++
8164 / 5012 / 1436
Регистрация: 29.11.2010
Сообщений: 13,455
23.12.2016, 16:11 6
На этом моменте (чисто виртуальные функции тоже могут иметь свою реализацию), у некоторых адептов начинается диссонанс. Однако это довольно удобный приём.
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
#include <iostream>
 
struct A
{
    virtual const char* what() const = 0;
    virtual ~A() = default;
};
 
const char* A::what() const
{
    return "Default";
}
 
struct B : A
{
    const char* what() const override { return "B"; }
};
 
struct C : A
{
    const char* what() const override { return A::what(); }
};
 
int main()
{
    //A a; // error
    B b;
    C c;
    std::cout << b.what() << std::endl << c.what();
}
Добавлено через 2 минуты
Цитата Сообщение от Oryel Посмотреть сообщение
дык.....
С того самого же места:
На языке программирования C++ абстрактный класс объявляется включением хотя бы одной чистой виртуальной функции, типа virtual _сигнатура_функции_ =0;, которая, как и другие, может быть заменена.
Добавлено через 5 минут
Цитата Сообщение от Oryel Посмотреть сообщение
Чья реализация метода вывозиться от наследника этих классов?
Если методы виртуальные, то выберется последний переопределённый вариант виртуальной функции (если не указывать область видимости явно). В этом и суть виртуальных функций.

Добавлено через 5 минут
Создание объекта базового класса с конструктором в protected:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
struct A
{
protected:
    A() {}
};
 
struct B : A
{
    using A::A;
};
 
int main()
{
    B b;
    A a = static_cast<A>(b);
}
0
11 / 1 / 1
Регистрация: 02.10.2015
Сообщений: 98
23.12.2016, 16:15  [ТС] 7
Цитата Сообщение от MrGluck Посмотреть сообщение
С того самого же места:
На языке программирования C++ абстрактный класс объявляется включением хотя бы одной чистой виртуальной функции, типа virtual _сигнатура_функции_ =0;, которая, как и другие, может быть заменена.
Страуструп:
...создать абстрактный класс, объявив его кон-
структор в разделе protected. Существует другой — более распространен-
ный — способ создания абстрактного класса: указать, что одна или несколько его
виртуальных функций будет замещена в производном классе...
2 способа. Тут вопрос не копи пастить вики..а идеи...идея абстрактнго класса предоставить интерфейс. Интрефейс - не имеет реализации. А как ты это сделаешь и как удобней - твое дело. Хочешь конструктор запрети:

в с++ 11 это через delete вроде делается...тут я кидаю в протект. Вот и абстрактный класс.

Я просто в дочерних классах из -за экономии кода не хотел переопределять what. Если я бы переопределил, я бы и вопрос не задал. Вопрос в том, могу ли я наделить абстрактный класс реализацией функции и унаследовать ее?
Если да, тогда чью релазацию унаследует класс потомок Базовый класс - > Мой класс исключений -> Конкретный класс потомок, который нас интересует.)

А ваш код не отвечает на вопрос. Он дает реализацию задачи переопределения методов.. Пока что я просто переопределил в классах метод, но мне интересен такой случай наследования.
Как его граммотно реализуют..?
0
Форумчанин
Эксперт CЭксперт С++
8164 / 5012 / 1436
Регистрация: 29.11.2010
Сообщений: 13,455
23.12.2016, 16:21 8
Цитата Сообщение от Oryel Посмотреть сообщение
могу ли я наделить абстрактный класс реализацией функции и унаследовать ее?
У меня как раз в примере абстрактный класс имеет реализацию чисто виртуальной функции.

Добавлено через 1 минуту
Цитата Сообщение от Oryel Посмотреть сообщение
в с++ 11 это через delete вроде делается
Но вы же сами говорите о наследовании. Такой класс просто не позволит создать потомков.
0
11 / 1 / 1
Регистрация: 02.10.2015
Сообщений: 98
23.12.2016, 16:24  [ТС] 9
в с++ 11 это через delete вроде делаетсяИсправляю...тут я думаю я может накосячил. на счет delete
Я поздно вообще вспомнил про это......отошел от компа...не суть. Забудем про астрактный класс

Как граммотно унаследовать такой случай, как у меня выше. Зачем потомкам переопределять метод, фактически копировать его?
C++
1
2
3
4
5
class cGeneralError : public cError{
            public:
                cGeneralError   ( const std::string &sErrString ) { sError_ = sErrString; }
                virtual const char* what( void ) const { return sError_.c_str(); }
        };
Если смысл наследования избежать копи паста.... вот и спрашиваю..как унаследовать граммотно метод и чью реализацию он вызовет

Хочу получить вот что
C++
1
2
3
4
5
class cGeneralError : public cErrorCan{
            public:
                cGeneralError   ( const std::string &sErrString ) { sError_ = sErrString; }
                // метод what наследуется от базового класса.
        };
0
Форумчанин
Эксперт CЭксперт С++
8164 / 5012 / 1436
Регистрация: 29.11.2010
Сообщений: 13,455
23.12.2016, 16:28 10
Всё просто.
В потомках нужна реализация по умолчанию или переопределённая - использовать виртуальные функции.
В потомках нужно требовать явного определения метода - использовать чисто виртуальные функции. При этом можно их реализовать и использовать как реализацию по умолчанию, но требование всё равно останется.

Добавлено через 3 минуты
Цитата Сообщение от Oryel Посмотреть сообщение
Зачем потомкам переопределять метод, фактически копировать его?
Не за чем, просто не переопределяйте его и будет вызвана последняя переопределённая функция.

Кстати, можно использовать конструкторы базового класса, если новых свойств он не содержит.
С помощью ключевого слова using (С++11).
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
struct A
{
    int x;
    A(const int x_) : x(x_) {}
};
 
struct B : A
{
    using A::A;
};
 
int main()
{
    B b(42);
}
0
11 / 1 / 1
Регистрация: 02.10.2015
Сообщений: 98
23.12.2016, 16:30  [ТС] 11
Это дык понятно. Было не понятно, я бы навреное это не написал бы.
Вот я переопределил функцию член. А в std::exception или другом подобной случае есть уже свое определение функции. Чью реализацию он унаследует?
Нужно вирутальное наследование?

Добавлено через 23 секунды
Это дык понятно. Было не понятно, я бы навреное это не написал бы.
Вот я переопределил функцию член. А в std::exception или другом подобной случае есть уже свое определение функции. Чью реализацию он унаследует?
Нужно вирутальное наследование?
0
Форумчанин
Эксперт CЭксперт С++
8164 / 5012 / 1436
Регистрация: 29.11.2010
Сообщений: 13,455
23.12.2016, 16:33 12
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
 
struct A
{
    virtual void foo() { std::cout << "Default\n"; }
    virtual ~A() = default;
};
 
struct B : A
{};
 
struct C: A
{
    void foo() override { std::cout << "C\n"; }
};
 
int main()
{
    B b;
    C c;
    b.foo();
    c.foo();
}
Добавлено через 1 минуту
Цитата Сообщение от Oryel Посмотреть сообщение
Чью реализацию он унаследует?
Я вам уже несколько раз писал:
Цитата Сообщение от MrGluck Посмотреть сообщение
будет вызвана последняя переопределённая функция.
Цитата Сообщение от Oryel Посмотреть сообщение
Нужно вирутальное наследование?
Опять же
Цитата Сообщение от MrGluck Посмотреть сообщение
Зачем? Виртуальное наследование нужно только для решения проблемы с ромбом при множественном наследовании.
У вас тут нет никакого множественного наследования.

Добавлено через 1 минуту
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
#include <iostream>
 
struct A
{
    virtual void foo() { std::cout << "Default\n"; }
    virtual ~A() = default;
};
 
struct B : A
{
    virtual void foo() override { std::cout << "B\n"; }
    virtual ~B() = default;
};
 
struct C: B
{};
 
struct D: C
{
    void foo() override { std::cout << "D\n"; }
};
 
int main()
{
    C c;
    D d;
    c.foo();
    d.foo();
}
0
11 / 1 / 1
Регистрация: 02.10.2015
Сообщений: 98
23.12.2016, 16:34  [ТС] 13
Добавлено через 48 секунд
Понятно. А где это оговоренно? что последняя переопределенная функция?
0
Форумчанин
Эксперт CЭксперт С++
8164 / 5012 / 1436
Регистрация: 29.11.2010
Сообщений: 13,455
23.12.2016, 16:44 14
Лучший ответ Сообщение было отмечено Oryel как решение

Решение

Цитата Сообщение от Oryel Посмотреть сообщение
Понятно. А где это оговоренно?
В стандарте
10.3 Virtual functions
2. If a virtual member function vf is declared in a class Base and in a class Derived, derived directly or indirectly
from Base, a member function vf with the same name, parameter-type-list (8.3.5), cv-qualification, and ref
qualifier (or absence of same) as Base::vf is declared, then Derived::vf is also virtual (whether or not it is
so declared) and it overrides113 Base::vf. For convenience we say that any virtual function overrides itself.
A virtual member function C::vf of a class object S is a final overrider unless the most derived class (1.8)
of which S is a base class subobject (if any) declares or inherits another member function that overrides vf.
In a derived class, if a virtual member function of a base class subobject has more than one final overrider
the program is ill-formed.
Добавлено через 3 минуты
Кстати, не поленился, поискал по поводу абстрактного класса:
10.4 Abstract classes
2. <...> A class is abstract if it has at least one pure virtual function.
0
11 / 1 / 1
Регистрация: 02.10.2015
Сообщений: 98
26.12.2016, 16:28  [ТС] 15
Эх . . . ну пусть будет так по букве стандарта. Спасибо за интересную беседу.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
26.12.2016, 16:28

Заказываю контрольные, курсовые, дипломные работы и диссертации здесь или здесь.

Разработать абстрактный класс класс Point для задания координаты
Народ, не буду врать на подобии &quot;помогите, не понимаю как сделать&quot; и т.п., говорю как есть, у меня...

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

Абстрактный класс, наследование, класс хранится в другом классе
Нужна помощь. Написать программу: 1 класс. Имеется абстрактный класс который описывает какую-то...

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


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

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

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