Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.75/4: Рейтинг темы: голосов - 4, средняя оценка - 4.75
igorbelykh
8 / 8 / 3
Регистрация: 01.03.2013
Сообщений: 85
1

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

07.03.2014, 17:15. Просмотров 728. Ответов 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)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
07.03.2014, 17:15
Ответы с готовыми решениями:

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

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

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

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

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

12
raccoonlove
Заблокирован
07.03.2014, 17:17 2
igorbelykh, в заголовке у вас написано, что ошибка в вызове чисто виртуальной функции, то есть виртуальной функции, не имеющей ни одной имплементации. Проверьте, вы что-то недореализовали.
0
igorbelykh
8 / 8 / 3
Регистрация: 01.03.2013
Сообщений: 85
07.03.2014, 17:27  [ТС] 3
Да у меня всего одна виртуальная функция и она реализована.
0
raccoonlove
Заблокирован
07.03.2014, 17:28 4
igorbelykh, тогда дайте весь код.
0
DrOffset
8937 / 4817 / 1178
Регистрация: 30.01.2014
Сообщений: 7,868
07.03.2014, 17:29 5
igorbelykh, случайно не из конструктора метод start() вызываешь?
0
igorbelykh
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
DrOffset
8937 / 4817 / 1178
Регистрация: 30.01.2014
Сообщений: 7,868
07.03.2014, 17:46 7
igorbelykh, в этом коде все нормально.
Неплохо бы посмотреть условия вызова start() и сам абстрактный класс.
0
igorbelykh
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
DrOffset
8937 / 4817 / 1178
Регистрация: 30.01.2014
Сообщений: 7,868
07.03.2014, 18:02 9
А если так попробовать?
C++
1
2
3
4
char* cmdName = "screenshot";
TaskDesktop task(cmdName);
AbstractTask * pTask = &task;
pTask->start();
0
igorbelykh
8 / 8 / 3
Регистрация: 01.03.2013
Сообщений: 85
07.03.2014, 18:12  [ТС] 10
То же самое
0
DrOffset
8937 / 4817 / 1178
Регистрация: 30.01.2014
Сообщений: 7,868
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
igorbelykh
8 / 8 / 3
Регистрация: 01.03.2013
Сообщений: 85
08.03.2014, 19:23  [ТС] 12
DrOffset, Спасибо большое. Правда я сам чуть раньше разобрался. Я просто сейчас все задачи помещаю в std::vector. Вернее помещаю ссылки на них. Так как TaskManager живет все время (т.е. где создаются эти задачи), то соответственно объект не успевает удалиться.
0
DrOffset
8937 / 4817 / 1178
Регистрация: 30.01.2014
Сообщений: 7,868
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
08.03.2014, 19:30
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
08.03.2014, 19:30

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

Ошибка no matching function for call to при работе с файлом
возникает ошибка no matching function for call to 'getline(std::string&amp;,...

Ошибка при вызове метода
Не пойму в чем ошибка... #include &lt;vector&gt; #include &lt;iostream&gt; template...


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

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

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