c ++ struct ссылочные типы - PullRequest
       7

c ++ struct ссылочные типы

1 голос
/ 15 сентября 2011

У меня есть класс с именем IAckHandler

class IAckHandler {
public:
    virtual ~IAckHandler();

    virtual void handleAck(long messageType, bool ackrcvd, uint8_t ackByte) = 0;
private:

};

Предполагаемое использование для наследования других классов, так что это в основном класс "interface".

Я использую очереди сообщений для отправки запросов в поток опроса (uart comm) и хочу передать IAckHandler в сообщение очереди сообщений. Структура выглядит так:

struct reqmsg
    {
        long int mtype;
        void (*reqHandler)(MasterRadioComm*, uint8_t*);
        IAckHandler* ackHandler;
        unsigned char mtext[NUM_INDICES];
    };

Вот функция отправки в очередь сообщений

void Uartcom::req_doSomething(IAckHandler& ackHandler)
{
    struct reqmsg req;
    if(ackHandler == NULL) req.ackHandler = this;
    else req.ackHandler = ackHandler;
    msgsnd(m_msgQueueKey, &req, sizeof(struct reqmsg) - sizeof(long), 0);
}

Но когда я передаю ссылку на IAckHandler, я получаю cannot convert ‘IAckHandler’ to ‘IAckHandler*’ in assignment.

Могу ли я вызвать req_doSomething (this) из другого класса, который наследует IAckHandler?

Ответы [ 6 ]

1 голос
/ 15 сентября 2011

У вас есть несколько проблем с вашей функцией req_doSomething:

  1. ackHandler - это ссылка, которая не может быть NULL.
  2. Вы пытаетесь назначить ссылку на указатель (req.ackHandler = &ackHandler; - это то, что вам нужно).

Однако, вероятно, лучше сделать что-то вроде этого:

void Uartcom::req_doSomething(IAckHandler * ackHandler)
{
    struct reqmsg req;
    if(ackHandler == NULL) req.ackHandler = this;
    else req.ackHandler = ackHandler;
    msgsnd(m_msgQueueKey, &req, sizeof(struct reqmsg) - sizeof(long), 0);
}
1 голос
/ 15 сентября 2011

Измените объявление функции, чтобы аргумент использовался как указатель, а не как ссылка:

void Uartcom::req_doSomething(IAckHandler * ackHandler)
                                         ^^^
1 голос
/ 15 сентября 2011

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

else req.ackHandler = &ackHandler;

и чтобы получить ссылку из указателя, вы переводите ее с помощью *ptr, поэтому вызов будет

req_doSomething(*this);

... или просто отбросьте ссылку и работайте полностью с указателями.

Обновление: Как указали другие, ссылка не может быть NULL.

0 голосов
/ 15 сентября 2011

Выглядит так, как будто вы должны объявить ackHandler как IAckHandler * в struct reqmsg. В C ++ ссылочные типы (например, IAckHandler &), хотя и реализованные с использованием указателей, обрабатываются синтаксически, как если бы они были встроенными объектами - в основном вам нужно работать с IAckHandler &, как если бы это был IAckHandler, а не IAckHandler *.

Следовательно, вы должны исправить свой код следующим образом:

void Uartcom::req_doSomething(IAckHandler& ackHandler)
{
    struct reqmsg req;
    if(ackHandler == NULL) req.ackHandler = this;
    else req.ackHandler = &ackHandler;
    msgsnd(m_msgQueueKey, &req, sizeof(struct reqmsg) - sizeof(long), 0);
}
0 голосов
/ 15 сентября 2011

Смотри внимательно.Член в структуре является «IAckHandler *», в то время как аргумент, полученный в функции установки, ссылается на IAckHandler.Что вы можете сделать, это:

req.ackHandler = &ackHandler;

С уважением,

Яти Сагаде

0 голосов
/ 15 сентября 2011

Он точно описывает, что вы должны делать.

сразу после адреса объекта к указателю:

req.ackHandler = &ackHandler;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...