8 / 8 / 3
Регистрация: 01.03.2013
Сообщений: 85
1

R6025 pure virtual function call при вызове метода, реализованного в дочернем классе

07.03.2014, 17:15. Показов 1482. Ответов 12
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Всем привет.
Вот такая ошибка у меня возникает при вызове метода, который реализован в дочернем классе, но потом он почему-то становится нереализованным. Проблема заключается, как я полагаю в приведении типов, но как ее избежать.
C++
1
2
3
4
5
6
7
8
9
10
11
void AbstractTask::start()
{
    CreateThread(NULL, 0, StaticThreadStart, (void*) this, 0, &myThreadId);
}
 
DWORD WINAPI AbstractTask::StaticThreadStart(void* Param)
{
    AbstractTask* This = (AbstractTask*)Param;
    This->run();
    return TRUE;
}
это отрывок абстрактного класса, который расширяется дочерними. В дочерних метод run() реализован. Что может быть не так?
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
07.03.2014, 17:15
Ответы с готовыми решениями:

R6025 pure virtual function call
Ошибка - r6025 pure virtual function call. Что не так? #include <iostream> #include <cstring>...

Pure virtual function call (не видит переопределенный метод)
Здравствуйте. Имеется базовый класс Cars и унаследованные от него классы Jeep, Hatchback, Sedan ...

Что означает ошибка pure virtual function call в NFS?
Что означает ошибка pure virtual function call?

Pure virtual function definition (C++11)
Объясните мне, как ламеру, для чего может понадобится определение чисто виртуальной функции?

12
Заблокирован
07.03.2014, 17:17 2
igorbelykh, в заголовке у вас написано, что ошибка в вызове чисто виртуальной функции, то есть виртуальной функции, не имеющей ни одной имплементации. Проверьте, вы что-то недореализовали.
0
8 / 8 / 3
Регистрация: 01.03.2013
Сообщений: 85
07.03.2014, 17:27  [ТС] 3
Да у меня всего одна виртуальная функция и она реализована.
0
Заблокирован
07.03.2014, 17:28 4
igorbelykh, тогда дайте весь код.
0
18347 / 9530 / 2329
Регистрация: 30.01.2014
Сообщений: 16,654
07.03.2014, 17:29 5
igorbelykh, случайно не из конструктора метод start() вызываешь?
0
8 / 8 / 3
Регистрация: 01.03.2013
Сообщений: 85
07.03.2014, 17:41  [ТС] 6
DrOffset, Нет, метод старт вызывается из другого класса. Дебаггер указывает на строку:
C++
1
    This->run();
вот подкласс, реализующий метод run()
Заголовочный файл
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#pragma once
#include "AbstractTask.h"
 
#pragma comment(lib, "Gdi32.lib")
 
class TaskDesktop :
    public AbstractTask
{
public:
    TaskDesktop(char* cmdName) :AbstractTask()
    {
        UINT len = strlen(cmdName) + 1;
        cmd = new char[len];
        strcpy_s(cmd, len, cmdName);
    }
    ~TaskDesktop();
protected:
    void run();
private:
    char* cmd;
};
тело
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include "stdafx.h"
#include "TaskDesktop.h"
 
 
 
 
TaskDesktop::~TaskDesktop()
{
    delete[] cmd;
}
 
void TaskDesktop::run()
{
    if (strcmp(cmd, "screenshot"))
    {
             std::cout << "Make a screenshot" << std::endl;
    }
}
0
18347 / 9530 / 2329
Регистрация: 30.01.2014
Сообщений: 16,654
07.03.2014, 17:46 7
igorbelykh, в этом коде все нормально.
Неплохо бы посмотреть условия вызова start() и сам абстрактный класс.
0
8 / 8 / 3
Регистрация: 01.03.2013
Сообщений: 85
07.03.2014, 17:53  [ТС] 8
DrOffset, вот вызов
C++
1
2
3
char* cmdName = "screenshot";
TaskDesktop task = TaskDesktop(cmdName);
task.start();
вот заголовок абстрактного класса
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#pragma once
#include <windows.h>
#include <iostream>
#include <thread>
 
#pragma comment(lib, "user32.lib")
#pragma comment(lib, "advapi32.lib")
 
class AbstractTask
{
public:
    AbstractTask();
    ~AbstractTask();
    void start();
    int getState();
    static DWORD WINAPI StaticThreadStart(void*);
protected:
    virtual void run()=0;
private:
    int iState;
    DWORD myThreadId;
    HANDLE myThread;
};
тело класса
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 "stdafx.h"
#include "AbstractTask.h"
 
 
AbstractTask::AbstractTask()
{
    iState = 0;
}
 
 
AbstractTask::~AbstractTask()
{
}
 
int AbstractTask::getState()
{
    return iState;
}
 
void AbstractTask::start()
{
    CreateThread(NULL, 0, StaticThreadStart, (void*) this, 0, &myThreadId);
}
 
DWORD WINAPI AbstractTask::StaticThreadStart(void* Param)
{
    AbstractTask* This = (AbstractTask*)Param;
    This->run();            // <-- ругается на эту строку
    return TRUE;
}
0
18347 / 9530 / 2329
Регистрация: 30.01.2014
Сообщений: 16,654
07.03.2014, 18:02 9
А если так попробовать?
C++
1
2
3
4
char* cmdName = "screenshot";
TaskDesktop task(cmdName);
AbstractTask * pTask = &task;
pTask->start();
0
8 / 8 / 3
Регистрация: 01.03.2013
Сообщений: 85
07.03.2014, 18:12  [ТС] 10
То же самое
0
18347 / 9530 / 2329
Регистрация: 30.01.2014
Сообщений: 16,654
07.03.2014, 19:02 11
Лучший ответ Сообщение было отмечено igorbelykh как решение

Решение

igorbelykh, А... ну так это, если там написано именно как в примере, то task уничтожился в конце области видимости, а поток продолжил работу с несуществующим объектом. Для пробы запусти такой код:
C++
1
2
3
char* cmdName = "screenshot";
AbstractTask * task = new TaskDesktop(cmdName);
task->start();
delete пока не вызывай.
1
8 / 8 / 3
Регистрация: 01.03.2013
Сообщений: 85
08.03.2014, 19:23  [ТС] 12
DrOffset, Спасибо большое. Правда я сам чуть раньше разобрался. Я просто сейчас все задачи помещаю в std::vector. Вернее помещаю ссылки на них. Так как TaskManager живет все время (т.е. где создаются эти задачи), то соответственно объект не успевает удалиться.
0
18347 / 9530 / 2329
Регистрация: 30.01.2014
Сообщений: 16,654
08.03.2014, 19:30 13
igorbelykh, ты главное вот еще что учти: ты должен класть в void* тот тип, который потом собираешься достать. Вот так:
C++
1
2
3
4
5
6
7
8
9
10
11
void AbstractTask::start()
{
    CreateThread(NULL, 0, StaticThreadStart, (AbstractTask*)this, 0, &myThreadId);
}
 
DWORD WINAPI AbstractTask::StaticThreadStart(void* Param)
{
    AbstractTask* This = (AbstractTask*)Param;
    This->run();
    return TRUE;
}
иначе при вызове метода start из наследника, туда попадет совсем другой this. А преобразование через void* от наследника к базе - это UB.
1
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
08.03.2014, 19:30
Помогаю со студенческими работами здесь

Не работает вызов метода PDO в дочернем классе
Есть класс: class Device { public static $device = array('id', 'name', 'type', 'buyDate',...

Protected abstract virtual base pure virtual private destructor
Хай, all) Вопрос не для начинающих и дурацкий) В разделе для экспертов публиковать не стал, чтобы...

"no matching function for call to" ошибка в вызове конструктора
имеется следующий класс makeworldtemplate.h #ifndef MAKEWORLDTEMPLATE_H #define...

Как обьявить переменную в одном классе и что бы ее было видно в дочернем классе
У меня есть основной класс с названием Root один из его членов наследует дочерний класс SubRoot....


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2023, CyberForum.ru