С Новым годом! Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 13, средняя оценка - 4.62
ArkTaS
1 / 1 / 0
Регистрация: 01.07.2013
Сообщений: 127
#1

Исключение для чисто виртуальной функции - C++

23.08.2013, 18:45. Просмотров 1904. Ответов 21
Метки нет (Все метки)

Читал вопросы на собеседованиях по С++ и столкнулся с pure virtual function call исключение. Объясните пожалуйста зачем это нужно ?! В моем понимании чист. вирт. функц. созданая для того что бы никто не создавал объекты этого класса.
Ссылка на источник http://habrahabr.ru/post/117996/ и копия ответа:
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
10. Как сгенерировать pure virtual function call исключение?
 
Ответ: Нужно вызвать чисто виртуальный метод в конструкторе родительского класса т.е. до создания дочернего, в котором этот метод реализован. Т.к. современный компилятор не даст это сделать напрямую, то нужно будет использовать промежуточный метод.
Пример:
class Base
{
public:
    Base()
    {
        base_func();
    }
    void base_func()
    {
        func(); // pure virtual function call exception
    }
    virtual void func() = 0;
};
class Derived : public Base
{
public:
    virtual void func()
    {
    }
};
Здесь нет ни throw генерировавшего некое исключение, ни объявления исключений
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
23.08.2013, 18:45
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Исключение для чисто виртуальной функции (C++):

НЕнаследование чисто виртуальной функции - C++
Доброго времени суток ! Есть абстрактный класс A с одной чисто виртуальной функцией. Есть два наследуемых класса В и С, которым...

В чем разница между виртуальной и чисто виртуальной функцией? - C++
в чем разница между виртуальной и чисто виртуальной функцией? virtual void print(){..} virtual void ex(..)=0;

Возможно ли? Базовый класс с чисто виртуальной функцией и наследники - C++
есть такая ситуация, есть базовый класс и от него 2 наследника. У наследников есть одинаковые функции, но имеющие разный тип принимаемого...

Указатель для вызова виртуальной функции - C++
Помогите разобраться в строении вызова виртуальной функции Если не сложно, объсните каждый указатель #include <iostream> ...

Чисто вирутальные функции в шаблонном классе - C++
Хотелось бы узнать, поддерживает ли это свойство Visual C++ 2010.

Вызвано исключение: нарушение доступа для чтения. Функции и двумерные массивы - C++
Здравствуйте. В процессе выполнения несложного учебного задания столкнулся с ошибкой. Подозреваю, что ошибка очень глупая и вызвана...

21
Kuzia domovenok
2060 / 1905 / 174
Регистрация: 25.03.2012
Сообщений: 6,564
Записей в блоге: 1
23.08.2013, 18:56 #2
Вот это да! Я понимаю, что так не должно работать, но никогда бы не подумал, что это скомпилируется! Точнее, вообще никогда не задумывался написать так!

Кстати, а как тогда поведёт себя эта программа? В Debug я словил исключение. А при запуске релизного экзешника что будет твориться?
0
Croessmah
Ушел
Эксперт CЭксперт С++
13558 / 7708 / 872
Регистрация: 27.09.2012
Сообщений: 18,996
Записей в блоге: 3
Завершенные тесты: 1
23.08.2013, 18:59 #3
Цитата Сообщение от ArkTaS Посмотреть сообщение
Здесь нет ни throw генерировавшего некое исключение, ни объявления исключений
Ну и что? Объект еще не создан а уже идет обращение к его членам

Добавлено через 24 секунды
Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
Я понимаю, что так не должно работать, но никогда бы не подумал, что это скомпилируется!
То что скомпилировалось не всегда работает

Добавлено через 2 минуты
Цитата Сообщение от ArkTaS Посмотреть сообщение
Объясните пожалуйста зачем это нужно ?
Например, чтобы проверить как Вы разбираетесь в наследовании и в полиморфизме в частности
1
ForEveR
В астрале
Эксперт С++
7983 / 4742 / 321
Регистрация: 24.06.2010
Сообщений: 10,547
Завершенные тесты: 3
23.08.2013, 19:43 #4
Kuzia domovenok, Право, очень странно задавать такие вопросы, учитывая что мы пишем на языке UB++.
Member functions can be called from a constructor (or destructor) of an abstract class; the effect of making a
virtual call (10.3) to a pure virtual function directly or indirectly for the object being created (or destroyed)
from such a constructor (or destructor) is undefined.
2
ArkTaS
1 / 1 / 0
Регистрация: 01.07.2013
Сообщений: 127
23.08.2013, 20:43  [ТС] #5
Цитата Сообщение от Croessmah Посмотреть сообщение
Например, чтобы проверить как Вы разбираетесь в наследовании и в полиморфизме в частности
И в чем здесь проявляется полиморфизм имею ввиду косвенный вызов чистой вирт. функции ?
Зачем в 17 и 22 строке дважды писать virtual ? Как словить это исключение, какой тип писать ? и зачем это вообще делать, если эффект андефайнед ?
0
Kastaneda
Jesus loves me
Эксперт С++
4697 / 2901 / 238
Регистрация: 12.12.2009
Сообщений: 7,388
Записей в блоге: 2
Завершенные тесты: 1
23.08.2013, 20:49 #6
Цитата Сообщение от ArkTaS Посмотреть сообщение
Зачем в 17 и 22 строке дважды писать virtual ?
Хороший стиль программирования.
Цитата Сообщение от ArkTaS Посмотреть сообщение
Как словить это исключение, какой тип писать ?
Это не языковое исключение (всмысле не те exception, которые есть в С++).
Цитата Сообщение от ArkTaS Посмотреть сообщение
и зачем это вообще делать, если эффект андефайнед ?
Язык позволяет это делать, но это не значит, что так можно делать. Ведь язык позволяет делать и так
C++
1
2
int array[0];
array[100] = 123;
1
Kuzia domovenok
2060 / 1905 / 174
Регистрация: 25.03.2012
Сообщений: 6,564
Записей в блоге: 1
23.08.2013, 20:53 #7
Цитата Сообщение от ArkTaS Посмотреть сообщение
и зачем это вообще делать, если эффект андефайнед ?
а зачем делить на ноль?
0
Croessmah
Ушел
Эксперт CЭксперт С++
13558 / 7708 / 872
Регистрация: 27.09.2012
Сообщений: 18,996
Записей в блоге: 3
Завершенные тесты: 1
23.08.2013, 20:58 #8
Цитата Сообщение от ArkTaS Посмотреть сообщение
И в чем здесь проявляется полиморфизм имею ввиду косвенный вызов чистой вирт. функции ?
Зачем в 17 и 22 строке дважды писать virtual ? Как словить это исключение, какой тип писать ? и зачем это вообще делать, если эффект андефайнед ?
Ну если так скажете на собеседовании, то скорее всего "Вам перезвонят"
0
ArkTaS
1 / 1 / 0
Регистрация: 01.07.2013
Сообщений: 127
23.08.2013, 21:20  [ТС] #9
Цитата Сообщение от Croessmah Посмотреть сообщение
И в чем здесь проявляется полиморфизм имею ввиду косвенный вызов чистой вирт. функции ?
Зачем в 17 и 22 строке дважды писать virtual ? Как словить это исключение, какой тип писать ? и зачем это вообще делать, если эффект андефайнед ?
Ну если так скажете на собеседовании, то скорее всего "Вам перезвонят"
Кто нибудь объясните где здесь полиморфизм именно не вирт наследование, а "косвенный вызов чистой вирт. функции " ??
0
ForEveR
В астрале
Эксперт С++
7983 / 4742 / 321
Регистрация: 24.06.2010
Сообщений: 10,547
Завершенные тесты: 3
23.08.2013, 21:35 #10
ArkTaS, Суть в том, что при вызове виртуальной функции из конструктора/деструктора будет вызван метод самого класса, а не потомка. В случае чисто-виртуальной функции это будет - произойдет что-то не то, что хотелось бы. Но при этом, здесь использована хитрость, которая мешает компилятору опознать вызов чисто-виртуальной функции из конструктора, ибо на самом деле вызов идет из функции класса, что является вполне нормальной практикой.
1
Tulosba
:)
Эксперт С++
4397 / 3233 / 297
Регистрация: 19.02.2013
Сообщений: 9,045
23.08.2013, 22:48 #11
Сталкивался с таким несколько раз. Если вызов идет явно из конструктора, то это обычно отлавливается на этапе компиляции. Если вызов идет косвенно, через функции-члены, то уже только в рантайме. Разные реализации при попытке вызова чисто-виртуальной функции в той или иной форме выводят сообщение об этом "pure virtual function call".
1
ArkTaS
1 / 1 / 0
Регистрация: 01.07.2013
Сообщений: 127
24.08.2013, 01:40  [ТС] #12
Цитата Сообщение от ForEveR Посмотреть сообщение
ArkTaS, Суть в том, что при вызове виртуальной функции из конструктора/деструктора будет вызван метод самого класса, а не потомка. В случае чисто-виртуальной функции это будет - произойдет что-то не то, что хотелось бы. Но при этом, здесь использована хитрость, которая мешает компилятору опознать вызов чисто-виртуальной функции из конструктора, ибо на самом деле вызов идет из функции класса, что является вполне нормальной практикой.
А в какой ситуации будет вызван метод потомка (вирт.) из базового класса ? если таковой ситуации нет то это не может быть полиморфизмом ?!
0
ForEveR
В астрале
Эксперт С++
7983 / 4742 / 321
Регистрация: 24.06.2010
Сообщений: 10,547
Завершенные тесты: 3
24.08.2013, 02:45 #13
ArkTaS, Если метод не будет вызван из конструктора/деструктора (прямо или косвенно).
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
#include <iostream>
 
class A
{
public:
   virtual ~A() {}
   void print()
   {
       print_impl();
   }
private:
    virtual void print_impl() = 0;
};
 
class B : public A
{
    void print_impl() { std::cout << "B" << std::endl; }
};
 
int main()
{
    A* b = new B();
    b->print();
}
https://ideone.com/uNrb5a
1
ArkTaS
1 / 1 / 0
Регистрация: 01.07.2013
Сообщений: 127
24.08.2013, 15:52  [ТС] #14
Цитата Сообщение от ForEveR Посмотреть сообщение
ArkTaS, Если метод не будет вызван из конструктора/деструктора (прямо или косвенно).
Читал Кернинга "Эфективное програмирование", Лафорте "ООП C++", больше понимания дал конечно Кернинг в вирт наследовании только вот как то в голове забилось что приватные члены не наследуются. После вашего приведенного кода, закралась мысль что где то я ошибся. Ну и практическим путем выяснилось что наследуются абсолютно все члены.
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
#include <iostream>
 
class A
{
public:
    A(){std::cout << " Aconstr " << std::endl;}
   virtual ~A() {}
   void print()
   {
       print_impl();
   }
private:
     void print_impl() {std::cout << " A " << std::endl;}
};
 
class B : public A
{
public:
     B() {std::cout << " Bconstr " << std::endl;}
   // void print_impl() { std::cout << " B " << std::endl; }
};
 
class C : public B
{
public:
    C(){std::cout << " Cconstr " << std::endl;}
 
    //    void print_impl() { std::cout << " C " << std::endl; }
};
int main()
{
    C* b = new C();
    b->print();
    system("pause");
    std::cout<<std::endl;
}
0
ForEveR
В астрале
Эксперт С++
7983 / 4742 / 321
Регистрация: 24.06.2010
Сообщений: 10,547
Завершенные тесты: 3
25.08.2013, 02:48 #15
ArkTaS, Наследуются все. Однако к приватным/защищенным нет доступа извне
0
25.08.2013, 02:48
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
25.08.2013, 02:48
Привет! Вот еще темы с ответами:

Компилятор С++ для генерации чисто двоичного формата - C++
Подскажите сабж. Нужно для написания ядра микро-операционки

Нужно ли прописывать конструктор и деструктор для чисто виртуального абстрактного класса - C++
Всем привет! Порылся в интернете, но не смог найти конкретного ответа на свой вопрос. Возможно я просто не смог грамотно сформулировать...

Смысл виртуальной функции? - C++
Добрый день, вопрос состоит в следующем, какой вообще смысл иметь виртуальную функцию? ну точней, вот если можно какой нибудь маленький...

Переопределение виртуальной функции - C++
Всем доброй ночи :) Есть базовый абстрактный класс и два производных класса (А и В), в которых я пытяюсь переопределить виртуальную...


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

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

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