2017-01-12 13 views
1

Я пытаюсь создать класс, в котором мы можем кодировать и декодировать разные структуры из и в char *.Как вызвать generic struct в C++

Я делаю это следующим образом, я сделал абстрактное общий класс, называемый CANgenericMsg с CANgenericMsg.cpp быть:

#include "CANgenericMsg.h" 

CANgenericMsg::CANgenericMsg() { 
    // TODO Auto-generated constructor stub 

} 

void CANgenericMsg::decode(char* chars) { 
    CANgenericMsg::str* data = reinterpret_cast<CANgenericMsg::str*>(chars); 
    structure = *data; 
} 

char* CANgenericMsg::encode() { 
    return reinterpret_cast<char*>(&structure); 
} 


CANgenericMsg::~CANgenericMsg() { 
    // TODO Auto-generated destructor stub 
} 

И с заголовком:

class CANgenericMsg { 
public: 
    CANgenericMsg(); 
    void decode(char* chars); 
    virtual ~CANgenericMsg(); 
    char* encode(); 
    virtual struct str structure; 
}; 

Этот класс является расширенные действительными классами, такими как CANintegermsg, в которых конструктор этого класса содержит структуру:

class CANintegermsg: public CANgenericMsg { 
public: 
    CANintegermsg(int i); 
    virtual ~CANintegermsg(); 

    struct str { 
     unsigned short int my_int; 
    } structure; 
}; 

Идея состоит в том, что вы можете установить определенный тип структуры в каждом расширенном классе. Проблема в том, что C++ не распознает виртуальные структуры. Я мог перемещать функции кодирования и декодирования в каждый расширенный класс, но поскольку их много, это приведет к дублированию кода. Существует ли опрятный способ использовать функции кодирования и декодирования, подобные этому?

+0

Рассмотрите также SWIG или IDL, такие как XPCOM или DCE/RPC IDL. – Ben

ответ

0

Вы можете использовать шаблоны:

template<class T> 
class CANGenericMsg 
{ 
public: 
    CANGenericMsg(const T val) : m_structureObj(val) {} 
    void decode(char* chars) 
    { 
     T* data = reinterpret_cast<T*>(chars); 
     m_structureObj = *data; 
    } 
    char* encode() 
    { 
     return reinterpret_cast<char*>(&m_structureObj); 
    } 
private: 
    T m_structureObj; 
}; 

struct StructUShortInt { unsigned short int my_int; }; 
using CANIntegerMsg = CANGenericMsg<StructUShortInt>; 
+0

Спасибо! Я так и не подумал об этом. У меня еще два вопроса: 1) Что конкретно происходит с конструктором CANgenericMsg? Я не знаком с этим синтаксисом, если честно. 2) Когда вы пытаетесь построить, я получаю сообщение об ошибке «using CANIntegerMsg». "error: ожидаемое вложенное имя-спецификатор перед 'CANIntegerMsg'". Зачем вам нужна ожидаемая спецификация имени в этой ситуации? –

+0

@DaanR, 1) он использовал [список инициализаторов] (http://en.cppreference.com/w/cpp/language/initializer_list) для инициализации m_structureObj, я изменил его на обычный экземпляр-конструктор. 2) Пожалуйста, проверьте [этот код] (http://melpon.org/wandbox/permlink/EGrO9qe8Cilwq9M4): он компилируется с большинством компиляторов. – AMA

+1

Большое спасибо за вашу помощь. По-видимому, мой компилятор не является большинством компиляторов, но, похоже, он работает только для обмена «используемой» строкой на: «typedef CANGenericMsg CANIntegerMsg;" –

1

Это звучит (пожалуйста, поправьте меня, если я ошибаюсь), как вы пытаетесь повторно реализовать что-то вроде Protocol Buffers (protobufs). Для достижения цели вы можете использовать комбинацию сообщений protobuf, под-сообщений и extensions.

Protobufs также легко converted to & parsed from текстовые и двоичные представления.

+0

Thakn вы за ваш ответ!Из того, что я читал, я думаю, что эти протобуфы подходят, но просто использование их для этого единственного примера создало бы большую сложность, на мой взгляд. Я думаю, что ответ «шаблона» от AMA выглядит проще. Пожалуйста, исправьте меня, если я ошибаюсь –

+0

@DaanR В самом деле, если есть только одно простое использование, вам может быть лучше свернуть адаптированную реализацию, чтобы избежать добавления зависимости от дополнительной библиотеки. Если вы начнете определять многие типы сообщений, и все выходит из-под контроля, пересмотреть с помощью стандартного решения :) – merlinND