11 / 11 / 0
Регистрация: 04.04.2014
Сообщений: 140
1

Механизм виртуальных функций

04.03.2015, 10:22. Показов 1740. Ответов 32
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Всем привет!
Имею базовый абстрактный класс:
C++
1
2
3
4
5
6
7
8
9
10
class Interface
{   
public:
        //функция детектирования устройства true - если команда прошла успешно
    virtual bool device_detected() = 0; 
        // функция отправки сообщения true - если команда прошла успешно
    virtual bool send(unsigned char data_msg) = 0;
        // функция приема сообщения true - если команда прошла успешно
    virtual bool recieve(unsigned char* data_msg) = 0;
};
И два класса от него унаследованных:
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
class ComInterface: public Interface, public ComPortForConverter
{
public:
    ComInterface();
    ~ComInterface();
    bool device_detected();
    bool send(unsigned char data_msg);
    bool recieve(unsigned char* data_msg);
};
 
class FtdiInterface: public Interface
{
public:
    FT_HANDLE ftHandle;
    FtdiInterface();
    ~FtdiInterface();
    bool device_detected();
    bool send(unsigned char data_msg);
    bool recieve(unsigned char* data_msg);
    bool open(std::ascii_string name);
 
protected:
    int address;
    FT_HANDLE ftHandleCopy;
};
Далее я хочу чтобы моя программа сама определяла по какому интерфейсу подключено устройство и присваивала указателю на базовый адрес объекта содержащего методы активного интерфейса, для чего пишу следующее:
C++
1
2
3
4
5
6
7
8
9
10
11
12
if(FTDI.device_detected() == true) 
    {
        ptrII = &FTDI;
        return true;
    }
 
    if(COM.detect_port() == true)
    {
        ptrII = &COM;
        return true;
    }
    return false;
FTDI и COM объекты класса FTDI-интерфейса и COM-интерфейся соответсвенно
Далее с отсальными методами я хочу работать через указатель, т.е. таким образом:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
bool CAN2USB::send_can_msg(canmsg_t *msg) 
{
    if(ptrII->send(msg->id1) != true) return false;
    if(ptrII->send(msg->id2) != true) return false;
    if(ptrII->send(msg->id3) != true) return false;
    if(ptrII->send(msg->id4) != true) return false;
    if(ptrII->send(msg->flags) != true) return false;
    if(ptrII->send(msg->length) != true) return false;
    if(ptrII->send(msg->data[0]) != true) return false;
    if(ptrII->send(msg->data[1]) != true) return false;
    if(ptrII->send(msg->data[2]) != true) return false;
    if(ptrII->send(msg->data[3]) != true) return false;
    if(ptrII->send(msg->data[4]) != true) return false;
    if(ptrII->send(msg->data[5]) != true) return false;
    if(ptrII->send(msg->data[6]) != true) return false;
    if(ptrII->send(msg->data[7]) != true) return false;
    char check;
    check = solve_check_sum(msg);
    if(ptrII->send(check) != true) return false;
    return true;
}
И эта конструкция работает, но до тех пор пока я не делаю из этого dll-библиотеку(моя задача создать именно DLL). Т.е. я это оттестировал в обычном MFC приложении и все работает, но стоит мне перенести этот код в DLL, как он перестает работать, но если написать не через указатель, а через конкретный экземпляр, то заработает(но такой вариант меня не устраивает), т.е. так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
bool CAN2USB::send_can_msg(canmsg_t *msg)
{
    if(FTDI.send(msg->id1) != true) return false;
    if(FTDI.send(msg->id2) != true) return false;
    if(FTDI.send(msg->id3) != true) return false;
    if(FTDI.send(msg->id4) != true) return false;
    if(FTDI.send(msg->flags) != true) return false;
    if(FTDI.send(msg->length) != true) return false;
    if(FTDI.send(msg->data[0]) != true) return false;
    if(FTDI.send(msg->data[1]) != true) return false;
    if(FTDI.send(msg->data[2]) != true) return false;
    if(FTDI.send(msg->data[3]) != true) return false;
    if(FTDI.send(msg->data[4]) != true) return false;
    if(FTDI.send(msg->data[5]) != true) return false;
    if(FTDI.send(msg->data[6]) != true) return false;
    if(FTDI.send(msg->data[7]) != true) return false;
    char check;
    check = solve_check_sum(msg);
    if(FTDI.send(check) != true) return false;
    return true;
}
Во время отладки выяснил, что адрес который я записываю в указатель, при выходе из функции обнаружения устройства и определения активного интерфейса, портиться, но происходит это именно при создании DLL, в обычном MFC ничего не портиться и код работает.
У кого какие мысли по этому поводу?
P.S. надеюсь получилось подробно описать, если что плохо разъяснил, спросите я еще подробней опишу

Добавлено через 1 минуту
Забыл добавить, конечно же указатель на базовый класс объявлен глобально
2
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
04.03.2015, 10:22
Ответы с готовыми решениями:

Наследование классов, механизм виртуальных функций
Выручайте !!! Программа должна содержать: • базовый класс Х, включающий два элемента х1, х2...

Иерархия классов. Механизм виртуальных функций
Создать в производном классе метод Run, определяющий: Значение (х1+х2)*у Есть наработки, но...

Таблица виртуальных функций
Доброго дня! Не могу найти, подскажите, пожалуйста, таблица виртуальных функций же только одна для...

Перегрузка виртуальных функций
please HELP! перегружаю виртуальную функцию в абстрактном классе. class ONE { virtual...

32
654 / 575 / 164
Регистрация: 13.12.2012
Сообщений: 2,124
04.03.2015, 10:24 2
Цитата Сообщение от takhvatulin Посмотреть сообщение
FTDI и COM объекты класса FTDI-интерфейса и COM-интерфейся соответсвенно
объекты то небось статичные, вот адреса то и портятся ну или , было бы неплохо если показали полнубю реализацию этого метода
0
11 / 11 / 0
Регистрация: 04.04.2014
Сообщений: 140
04.03.2015, 10:25  [ТС] 3
Цитата Сообщение от aLarman Посмотреть сообщение
было бы неплохо если показали полнубю реализацию этого метода
Какого именно метода?
0
654 / 575 / 164
Регистрация: 13.12.2012
Сообщений: 2,124
04.03.2015, 10:26 4
Цитата Сообщение от takhvatulin Посмотреть сообщение
Далее я хочу чтобы моя программа сама определяла по какому интерфейсу подключено устройство и присваивала указателю на базовый адрес объекта содержащего методы активного интерфейса, для чего пишу следующее:
вот этого
0
11 / 11 / 0
Регистрация: 04.04.2014
Сообщений: 140
04.03.2015, 10:26  [ТС] 5
Цитата Сообщение от aLarman Посмотреть сообщение
объекты то небось статичные
Статичные имеется ввиду созданные без выделения динамической памяти?
0
654 / 575 / 164
Регистрация: 13.12.2012
Сообщений: 2,124
04.03.2015, 10:26 6
Цитата Сообщение от takhvatulin Посмотреть сообщение
Статичные имеется ввиду созданные без выделения динамической памяти?
угу
0
11 / 11 / 0
Регистрация: 04.04.2014
Сообщений: 140
04.03.2015, 10:30  [ТС] 7
Цитата Сообщение от aLarman Посмотреть сообщение
вот этого
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
bool CAN2USB::device_detected()
{       
    if(FTDI.device_detected() == true)
    {
        ptrII = &FTDI;
        return true;
    }
    if(COM.detect_port() == true)
    {
        ptrII = &COM;
        return true;
    }
    return false;
}
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
37
38
bool FtdiInterface::device_detected()
{
    FT_STATUS ftStatus;
    DWORD numDevs;
    char* NameList[16];
    char num;
    for(int i = 0; i < 15; i++)
    {
        NameList[i] = new char[64]; 
    }
    NameList[15] = NULL;
    
    FT_ListDevices(NameList,&numDevs,FT_LIST_ALL|FT_OPEN_BY_DESCRIPTION);
    
    std::tcstring str = _T("");
    for(int i = 0; i < 15; i++)
    {
        str = std::ascii2unicode(NameList[i]);
        if(str.compare(DEVICE_NAME) == 0)
        {
            num = i;
            break;
        }
    }
    if(open(NameList[num]) == true)
    {
        for(int i = 0; i < 15; i++)
        {
            delete NameList[i];
        }
        return true;
    }
    for(int i = 0; i < 15; i++)
    {
        delete NameList[i];
    }
    return false;
}
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
37
38
39
40
41
bool ComPortForConverter::detect_port()
{
    if(get_object_state() == S_OK) 
    {
        return true;
    }
    for(int i = 1; i<16; i++)
        {
            Z::Byte buf;
            TCHAR tmpBuf[20];
            _stprintf(tmpBuf, _T("\\\\.\\COM%d"), i); 
            set_filename(tmpBuf);
            if(get_ready()) continue;
            Z::Result result = S_OK;
            result |= send_byte(KEY_DETECT);
            for(int j = 0; j < 14; j++)
            {
                result |= send_byte(0xff);
            }
            if(result != S_OK) continue;
            Sleep(25);
            if(recieve_byte(&buf) == S_OK && buf == KEY_DETECT)
            {
                return true;
            }
            complete();
        }
    return false;
 
 
bool ComInterface::device_detected()
{
    if(ComPortForConverter::detect_port() == true) 
    {
        return true;
    }
    else
    {
        return false;
    }
}
Добавлено через 33 секунды
Цитата Сообщение от aLarman Посмотреть сообщение
угу
Так и есть, динамически я память нигде не выделял. Сейчас попробую
0
654 / 575 / 164
Регистрация: 13.12.2012
Сообщений: 2,124
04.03.2015, 10:33 8
Цитата Сообщение от takhvatulin Посмотреть сообщение
bool CAN2USB::device_detected()
переменные FTDI и COM где расположены? поля класса CAN2USB ?
0
11 / 11 / 0
Регистрация: 04.04.2014
Сообщений: 140
04.03.2015, 10:34  [ТС] 9
Да
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
37
38
39
40
41
42
class CAN2USB: public Thread // здесь список классов родителей чьи возможности будут использоваться для работы класса например "Thread" для организации нитки приема сообщений от конвертора
{
    // здесь будут функции с помощью которых класс общается с внешним миром
public:
    CAN2USB();
    ~CAN2USB();
        // функция проверяющая наличие устройства (нашего CANUSB конвертора) true - устройство обнаружено; false - устройство не обнаружено
    bool device_detected(); 
        // функция передающая конвертору команду которая запрещает контроллеру принемать CAN сообщения из CAN линии возвращает true - если команда прошла успешно
    bool recieve_denied();
        // функция передающая конвертору команду которая разрешает контроллеру принемать CAN сообщения из CAN линии возвращает true - если команда прошла успешно
    bool recieve_allowed();
        // функция запрашивающая у конвертора статус работы приемника true - если прием разрешен и false - если прием запрещен
    bool recieve_access();
        // функция возвращающая количество принятых но еще непрочитаных CAN сообщений
    unsigned get_recieve_state(); 
        // функция возвращающая первое принятое но не прочитанное CAN сообщение (при этои очередь не прочитанных сообщений уменьшаеца на еденицу)
    canmsg_t recieve_can_msg();
        // функция принимающая в себя указатель на CAN сообщение которое будет отправлено в конвертер для передачи по CAN линии
        // возвращает true если контроллер успешно отправил CAN сообщение и false в противном случае
    bool send_can_msg(canmsg_t* msg);
 
    // здесь структуры данных, классы и функции организующие работу класса CAN2USB инкапсулированные (неимеющие возможности общаться с внешним миром)
    // собственно здесь твоя работа ))
    
protected:
 
    ComPortExt Comport;
    Z::Result activate();
    void recieve();
    void decode();
    void decode2();
    char solve_check_sum(canmsg_t* msg);
 
protected:
    Queue <Z::Byte> Queue_msg;
    Queue <canmsg_t> QueueCanMsg;
    
    FtdiInterface FTDI;
    ComInterface COM;
    Interface* ptrII;
};
0
aLarman
04.03.2015, 10:35
  #10

Не по теме:

takhvatulin, кстати в наследнике неплохо написать что методы тоже виртуальные(чтоб потом самому же не запутаться)

0
11 / 11 / 0
Регистрация: 04.04.2014
Сообщений: 140
04.03.2015, 10:35  [ТС] 11
Верно выделил память?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
bool CAN2USB::device_detected()
{       
    if(FTDI.device_detected() == true)
    {
        ptrII = new FTDI;
        ptrII = &FtdiInterface;
        return true;
    }
    delete ptrII;
    if(COM.detect_port() == true)
    {
        ptrII = new ComInterface;
        ptrII = &COM;
        return true;
    }
    delete ptrII;
    return false;
}
0
654 / 575 / 164
Регистрация: 13.12.2012
Сообщений: 2,124
04.03.2015, 10:36 12
Цитата Сообщение от takhvatulin Посмотреть сообщение
class Interface
и где виртуальный деструктор - раз такая пьянка пошла

Добавлено через 51 секунду
Цитата Сообщение от takhvatulin Посмотреть сообщение
Верно выделил память?
нет, Вы, кажется, что то перепутали, не могли бы показать весь класс CAN2USB
0
11 / 11 / 0
Регистрация: 04.04.2014
Сообщений: 140
04.03.2015, 10:38  [ТС] 13
Цитата Сообщение от aLarman Посмотреть сообщение
takhvatulin, кстати в наследнике неплохо написать что методы тоже виртуальные(чтоб потом самому же не запутаться)
В смысле комментарий написать, или какой то строчкой кода??

Цитата Сообщение от aLarman Посмотреть сообщение
и где виртуальный деструктор - раз такая пьянка пошла
Вообще о таком не думал

Цитата Сообщение от aLarman Посмотреть сообщение
не могли бы показать весь класс CAN2USB
Я его показал немного выше

Добавлено через 1 минуту
Цитата Сообщение от takhvatulin Посмотреть сообщение
ptrII = new FTDI;
ptrII = &FtdiInterface;
В этом моменте ошибку поправил
0
654 / 575 / 164
Регистрация: 13.12.2012
Сообщений: 2,124
04.03.2015, 10:41 14
Цитата Сообщение от takhvatulin Посмотреть сообщение
В этом моменте ошибку поправил
а вижу что они поля класса, если честно пока нет идей...
0
11 / 11 / 0
Регистрация: 04.04.2014
Сообщений: 140
04.03.2015, 10:42  [ТС] 15
Только что попробовал с динамическим выделением памяти, не заработало...
0
654 / 575 / 164
Регистрация: 13.12.2012
Сообщений: 2,124
04.03.2015, 10:47 16
а попробуйте так,
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
bool CAN2USB::device_detected()
{       
ptrII = new FTDI;
    if(ptrII->device_detected() == true)
    {
        return true;
    }
    delete ptrII;
ptrII = new ComInterface;
    if(ptrII->device_detected() == true)
    {
        return true;
    }
    delete ptrII;
ptrII = NULL;
    return false;
}
0
11 / 11 / 0
Регистрация: 04.04.2014
Сообщений: 140
04.03.2015, 10:49  [ТС] 17
Почему в одном случае вы выделили память под объект класса
Цитата Сообщение от aLarman Посмотреть сообщение
ptrII = new FTDI;
,
а во втором под класс:
Цитата Сообщение от aLarman Посмотреть сообщение
ptrII = new ComInterface;
опечатка?
0
654 / 575 / 164
Регистрация: 13.12.2012
Сообщений: 2,124
04.03.2015, 10:52 18
Цитата Сообщение от takhvatulin Посмотреть сообщение
а во втором под класс:
нельзя выделать память под класс, ни какой очепятки нет

Добавлено через 1 минуту
прошу прощения, да опечатался
C++
1
ptrII = new FtdiInterface;
должно быть
0
11 / 11 / 0
Регистрация: 04.04.2014
Сообщений: 140
04.03.2015, 10:55  [ТС] 19
Даже не скомпилилось: 1>.\CAN2USB.cpp(28) : error C2039: 'detect_port' : is not a member of 'Interface'
Кстати забыл добавить, приложение в которую встраиваю DLL вылетает, но прежде чем вылететь функция детектирования выполняется и устройство обнаруживается
0
654 / 575 / 164
Регистрация: 13.12.2012
Сообщений: 2,124
04.03.2015, 10:56 20
Цитата Сообщение от takhvatulin Посмотреть сообщение
Даже не скомпилилось:
ну так есесно, проверьте еще раз мой пример, я его исправлял

Добавлено через 52 секунды
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
bool CAN2USB::device_detected()
{       
ptrII = new FtdiInterface;
    if(ptrII->device_detected() == true)
    {
        return true;
    }
    delete ptrII;
ptrII = new ComInterface;
    if(ptrII->device_detected() == true)
    {
        return true;
    }
    delete ptrII;
ptrII = NULL;
    return false;
}
вобщем так
0
04.03.2015, 10:56
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
04.03.2015, 10:56
Помогаю со студенческими работами здесь

Использование виртуальных функций
Дан класс &quot;треугольник&quot;, который определяется длиной одной из сторон и значениями прилегающих...

Вызов виртуальных функций
Доброго времени суток, форумчане! Стоит такая задача: Есть класс, который содержит три чисто...

Использование виртуальных функций
Программа берет данные из двух файлов, в которых есть дата и количество проданных билетов, и...

Таблица виртуальных функций
объясните плиз кто разбирается.. есть абстрактный класс с двумя виртуальными функциями, от него...


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

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

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