С Новым годом! Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.75/8: Рейтинг темы: голосов - 8, средняя оценка - 4.75
51 / 51 / 8
Регистрация: 31.10.2012
Сообщений: 481

Работа с абстрактным классом

07.01.2016, 21:42. Показов 1816. Ответов 34
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Доброго времени суток!
Имеется небольшой класс:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <irrlicht.h>
 
class EngineInit
{
public:
    IrrlichtDevice* device = 0;
    ISceneManager* smgr = 0;
    IVideoDriver* driver = 0;
    IGUIEnvironment* guienv = 0;
 
    ILightSceneNode* sun;
    vector3df pos;
 
    int initialise();
};
C++
1
2
3
4
5
int EngineInit::initialiseEngine()
{
    driver = device->getVideoDriver();
    guienv = device->getGUIEnvironment();
}
Выдает сегфолт на driver = device->getVideoDriver(). Известно, что классы IrrlichtDevice и далее -- абстрактные. Я прекрасно понимаю, что пишу программу неправильно.
Если же исключить ООП и писать реализацию напрямую в функции main, то проблемы не наблюдается.
Как нужно исправить программу, чтобы не получать сегфолт?
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
07.01.2016, 21:42
Ответы с готовыми решениями:

Полиморфизм с абстрактным классом
Добрий день, нуждаюсь в помощи. У меня есть абстрактный класс IStudent_Manip и производный класс Student_Manipulator. Хочу сделать...

Непонятки с абстрактным классом
У нуба возник вопрос :) Вот объявляю я абстрактный Inline класс. Ну под инлайн я имею ввиду, что он без cpp, реализация в H. #pragma...

Ошибка при работе с абстрактным классом pair
Всем доброго времени суток, стоит задача создать абстрактный класс pair и создать от него производный класс complex, определив при этом...

34
Эксперт С++
1675 / 1047 / 174
Регистрация: 27.09.2009
Сообщений: 1,945
07.01.2016, 22:34
Ну изначально-то в device нолик. Неудивительно, что при обращении к нему сегфолты возникают. А надо откуда-то взять указатель на полноценный объект. Как-то он должен в Irrlicht создаваться.
0
51 / 51 / 8
Регистрация: 31.10.2012
Сообщений: 481
07.01.2016, 22:57  [ТС]
Nick Alte, нолик -- ясное дело. Если, например, без классов я напишу так:
C++
1
2
3
4
5
6
IrrlichtDevice* device = 0;
IVideoDriver* driver = 0;
int main ()
{
driver = device->getVideoDriver ();
}
... то все будет прекрасно.
0
Эксперт С++
1675 / 1047 / 174
Регистрация: 27.09.2009
Сообщений: 1,945
08.01.2016, 07:27
Цитата Сообщение от SanchezPluz Посмотреть сообщение
... то все будет прекрасно.
Нет, не будет. Будет всё тот же сегфолт.

Гугление официального сайта Irrlicht, переход в туториалы, из них первый - Hello World, общее время меньше минуты. Видим следующее:
C++
1
IrrlichtDevice *device = createDevice( video::EDT_SOFTWARE, dimension2d<u32>(640, 480), 16, false, false, false, 0);
Ведь просто же всё, зачем заниматься ерундой?
1
Эксперт С++
4986 / 3093 / 456
Регистрация: 10.11.2010
Сообщений: 11,170
Записей в блоге: 10
08.01.2016, 09:45
Цитата Сообщение от SanchezPluz Посмотреть сообщение
... то все будет прекрасно.
Не будет и быть не может.
0
51 / 51 / 8
Регистрация: 31.10.2012
Сообщений: 481
08.01.2016, 10:27  [ТС]
Nick Alte, я уроки уже по десять раз прокурил, в очередной нового ничего не открою.
Просто по своей невнимательности не учел, что эта строка должна идти первой. Вопрос закрыт.
0
 Аватар для Kastaneda
5232 / 3205 / 362
Регистрация: 12.12.2009
Сообщений: 8,143
Записей в блоге: 2
08.01.2016, 11:13
Цитата Сообщение от Nick Alte Посмотреть сообщение
Нет, не будет. Будет всё тот же сегфолт.
Не будет, 0 просто передается как this в метод, если внутри метода не происходит обращения к членам, то все пройдет гладко.

Не по теме:

Хотя на днях как раз на форуме было высказано мнение, что это UB, но не уверен. Думаю тут не С++ стандарт курить надо, а что нибудь типа x86 abi, лень разбираться. Опираясь на мои знания это вроде не UB на x86.

0
Эксперт С++
1675 / 1047 / 174
Регистрация: 27.09.2009
Сообщений: 1,945
08.01.2016, 13:28
Цитата Сообщение от Kastaneda Посмотреть сообщение
на форуме было высказано мнение, что это UB, но не уверен
Если бы не обращался, то таки UB.

Вот только конкретно этот метод вполне себе обращается и вполне ожидаемо сегфолтит.
0
08.01.2016, 13:37

Не по теме:

Цитата Сообщение от Nick Alte Посмотреть сообщение
Если бы не обращался, то таки UB.
Ну вообще thiscall (и позднее конвенции для x86_64) нам говорит, что разыменования не будет, С++ стандарт говорит, что запись ptr-> идентична (*ptr).. Нужно для себя решить кто из них сильнее :) На уровне языка может и UB, но мне кажется т.к. thiscall тут перетягивает одеяло на себя, то можно считать что все вполне definded.
Хотя если забыть об архитектуре и говорить только терминами языка, то да, может UB.

0
50 / 49 / 10
Регистрация: 24.01.2010
Сообщений: 225
08.01.2016, 19:37
опс...
не досмотр
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
08.01.2016, 23:38
Цитата Сообщение от Kastaneda Посмотреть сообщение
Ну вообще thiscall (и позднее конвенции для x86_64) нам говорит, что разыменования не будет
нет, не говорит.
0
 Аватар для Kastaneda
5232 / 3205 / 362
Регистрация: 12.12.2009
Сообщений: 8,143
Записей в блоге: 2
09.01.2016, 07:31
Цитата Сообщение от hoggy Посмотреть сообщение
нет, не говорит.
скажем так - оно не говорит, что разыменование будет.

Добавлено через 8 минут

Не по теме:

Полез гуглить что-нибудь на эту тему, интересную вещь нашел

/* объясняют что NULL передается как this, бла бла бла */
Microsoft's MFC function GetSafeHwnd actually relies on this behavior. I don't know what they were smoking.
реально GetSafeHwnd допускает вызов через null pointer

0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
09.01.2016, 10:11

Не по теме:

Цитата Сообщение от Kastaneda Посмотреть сообщение
реально GetSafeHwnd допускает вызов через null pointer
это не показательно.
разработчики платформы запросто используют
не корректные с точки зрения стандарта ходы.

C++
1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
 
struct example
{
    int m;
};
 
int main()
{
    std::cout << "hello, world!\n";
    std::cout << offsetof(example, m) << std::endl;
}
stddef.h
C++
1
2
3
4
5
#ifdef _WIN64
#define offsetof(s,m)   (size_t)( (ptrdiff_t)&reinterpret_cast<const volatile char&>((((s *)0)->m)) )
#else  /* _WIN64 */
#define offsetof(s,m)   (size_t)&reinterpret_cast<const volatile char&>((((s *)0)->m))
#endif  /* _WIN64 */
обычно, всякого рода гнусные хаки слетают при оптимизациях.
здесь же, как мы видим, квалификатор volatile запрещает компилятору
оптимизировать конструкцию.

однако, от этого UB не перестает быть UB.
и не стоит им уподобляться.

эти ребята не просто знают тонкости своего компилятора,
но и умеют заставить его по особенному
собирать код своих библиотек.

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

все это прозрачно для тех пользователей,
у которых хватило ума не эксплуатировать
хаки в собственном коде напрямую.

что бы не получилось, как с бустовским typeof.
вот где площадка для экспериментов.
там используют любые платформо-специфичные хаки.

студийная реализация завязалась на баге в Visual Studio 7.1
(автоматический id времени компиляции)
после исправления которого,
лососнула тунца вплоть до выхода delctype

в том, что касается MFC - есть ряд драконовских ограничений.
например, связанные с множественным наследованием:

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
#include <iostream>
 
struct msvc
{
    bool is_valid()const { return this ? true : false; }
};
 
struct trololo
{
    int m = 33;
};
 
// при множественном наследовании
// первым всегда должен идти майкросотовский стафф
struct app: trololo, msvc {};
 
int main()
{
    std::cout << "hello, world!\n";
 
    app* p = nullptr;
 
        //что бы не получилась вот такая жёпь
    std::cout << "is valid? (must be 0) " << p->is_valid() << '\n';
}
и ещё вагон и тележка дыр в безопасности.

или вот код:
C++
1
2
3
4
5
    auto* p = GetDlgItem(IDC_ANIMATE2);
    assert(p && "IDC_ANIMATE1 not exist");
 
    CAnimateCtrl* anim 
        = static_cast<CAnimateCtrl*>(p);
в доке описаны случаи когда приведение допустимо, и даже рекомендуемо
однако, технически, это - сумасшедший каст теплого к мягкому.

работая с MFC, нужно быть оч аккуратным,
и внимательно читать доки.



Добавлено через 12 минут
Цитата Сообщение от Kastaneda Посмотреть сообщение
скажем так - оно не говорит, что разыменование будет.
оно вообще никаким боком не касается того,
какой путь пришлось пройти аргументам,
что бы оказаться на стеке функции.

единственная компетенция соглашения о вызове:
как упакованы аргументы по итогу.

и кстати, компиляторы при оптимизациях имеют полное право
покласть на это соглашение с большим прибором.


компиляторы закладываются, что код не содержит UB,
а значит всякие засранцы не будут писать такой код:
(последний пример)
Static члены класса

а значит можно сэкономить,
пробросив аргументы как нибудь через регистры,
а не стек.

"честный" thiscall будет, только если там элипсис, или volatile,
или какие нибудь волшебные слова компилятора:
Как гарантировать передачу единственного параметра через стек?
0
 Аватар для Kastaneda
5232 / 3205 / 362
Регистрация: 12.12.2009
Сообщений: 8,143
Записей в блоге: 2
09.01.2016, 14:43
Цитата Сообщение от hoggy Посмотреть сообщение
C++
1
2
//что бы не получилась вот такая жёпь
* * std::cout << "is valid? (must be 0) " << p->is_valid() << '\n';
не понял что не так с этим кодом?

Добавлено через 4 минуты
касательно
C++
1
0 -> func();
здесь и в соседней теме я пытался донести, что несмотря на то, что стандарт С++ говорит нам, что это UB в данном конкретном случае (вызов ф-ции члена) мы знаем как оно реально работает на x86 и можем смело ожидать, что разыменования не будет. Это не оптимизация, это вполне логичное поведение компилятора.
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
09.01.2016, 17:22
Цитата Сообщение от Kastaneda Посмотреть сообщение
не понял что не так с этим кодом?
вернет 1, очевидно жеж.

Добавлено через 51 секунду
Цитата Сообщение от Kastaneda Посмотреть сообщение
что разыменования не будет
будет.
0
 Аватар для Kastaneda
5232 / 3205 / 362
Регистрация: 12.12.2009
Сообщений: 8,143
Записей в блоге: 2
09.01.2016, 17:29
Цитата Сообщение от hoggy Посмотреть сообщение
будет.
спор бессмысленый, я говорю не будет, ты говоришь будет.

Цитата Сообщение от hoggy Посмотреть сообщение
вернет 1, очевидно жеж.
Это фишка MFC или что? Там какой-то свой метакомпилятор типа как в qt?
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
09.01.2016, 17:35
Цитата Сообщение от Kastaneda Посмотреть сообщение
спор бессмысленый, я говорю не будет, ты говоришь будет.
не я. стандарт.

Цитата Сообщение от Kastaneda Посмотреть сообщение
Это фишка MFC или что?
это фишка с++.

я малость поспешил.
вот правильная иллюстрация:

http://rextester.com/OSFPG49584

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
#include <iostream>
 
struct msvc
{
    bool is_valid()const { return this ? true : false; }
    
    int v=999;
};
 
struct trololo
{
    int m = 33;
};
 
// при множественном наследовании
// первым всегда должен идти майкросотовский стафф
struct app: trololo, msvc {};
 
int main()
{
    std::cout << "hello, world!\n";
 
    app* p = nullptr;
 
        //что бы не получилась вот такая жёпь
    std::cout << "is valid? (must be 0) " << p->is_valid() << '\n';
}
выводит 1.

потому что указатель p совпадает с началом подобъекта trololo.
в то время, как подобъект msvc отстоит от начала объекта на некоторое смещение,
определяемое данными-членами и выравниванием.

когда нужно запустить метод is_valid,
то обращение идет к подобъекту msvc,
компилятор автоматически выполняет корректировку смещения.
поэтому нулевое p не совпадает с this подобъекта msvc.
0
 Аватар для Kastaneda
5232 / 3205 / 362
Регистрация: 12.12.2009
Сообщений: 8,143
Записей в блоге: 2
09.01.2016, 17:48
Цитата Сообщение от hoggy Посмотреть сообщение
не я. стандарт.
но разыменования не происходит при включении в комплияторе строго следования стандарту.
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
09.01.2016, 19:10
Цитата Сообщение от Kastaneda Посмотреть сообщение
но разыменования не происходит при включении в комплияторе строго следования стандарту.
происходит.
0
10.01.2016, 17:13

Не по теме:

hoggy, не хочу приводить рабочий пример и ассемблерный выхлоп потому что:
- я знаю, что ты можешь получить это без меня
- я знаю, что ты и так знаешь результат

посему дальнейший спор считаю абсолютно бессмысленным.

0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
10.01.2016, 17:13
Помогаю со студенческими работами здесь

Создать иерархию наследования с абстрактным базовым классом
Доброго времени суток! Помогите, пожалуйста, сделать: 2) Создать абстрактный базовый класс с виртуальной функцией &quot;Площадь&quot;....

Работа с классом
Работа с классом, карточку отдела кадров(обеспечить вывод на экран в удобном виде, печать сообщения при достижении пенсионного возраста)....

работа с классом
пишу класс быстрой математики (знаю что многие делали в инете дофига всего, но всё же) сделал таблицу корней в общем то всё работает...

Работа с классом
Необходимо написать класс который будет переводить из 16-ой системы счисления числа в 10-ю систему счисления, классы только неделю назад...

работа с классом
Напсал код: #include &lt;IOSTREAM&gt; #include &lt;fstream&gt; #include &quot;rus.h&quot; #include &quot;work.h&quot; using namespace std; class Temperatura ...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
Расчёт токов в цепи постоянного тока
igorrr37 05.01.2026
/ * Дана цепь постоянного тока с сопротивлениями и источниками (напряжения, ЭДС и тока). Найти токи и напряжения во всех элементах. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа и. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru