2012-04-27 2 views
1

Я хочу создать очень общий чистый виртуальный класс i_BIS_Data, который будет наследоваться уникальными классами BIS_Data.Перегрузка структур в C++

class i_BIS_Data 
{ 
public: 

i_BIS_Data(void) { } 
virtual ~i_BIS_Data(void) { } 

    virtual void setData(bis_data data) = 0; 
}; 

Я хочу, чтобы все мои дети i_BIS_Data определить bis_data-структуру, как и все они будут разными. Я ожидаю, что мой ребенок класс выглядеть примерно следующим образом:

class BIS_0192_Aircraft_ID_Data : i_BIS_Data 
{ 
    public: 

    struct bis_data 
    { 
    UInt16 acid; 
    UInt16 parity; 
    }; 

    void setData(bis_data data){ m_data.parity = data.parity; 
          m_data.acid = data.acid; } 
} 

Когда я пытаюсь скомпилировать класс, который использует BIS_0192_Aircraft_ID_Data, я получаю следующее сообщение об ошибке: Ошибка C2061: синтаксическая ошибка: идентификатор «bis_data». Я верю в это, потому что я не определил bis_data в родительском классе.

Так можно ли «перегрузить» структуру и разрешить нескольким классам детей определять, что такое bis_data?

ответ

3
template<typename BIS_DATA_T> 
class i_BIS_Data 
{ 
     typedef BIS_DATA_T bis_data; 
     ... 
     virtual void setData(bis_data data) = 0; 
}; 

struct bis_0192_data 
{ 
    UInt16 acid; 
    UInt16 parity; 
}; 

class BIS_0192_Aircraft_ID_Data : public i_BIS_Data<bis_0192_data> 
{ 
    public: 
    void setData(bis_data data){ m_data.parity = data.parity; 
         m_data.acid = data.acid; } 
}; 

Это должно работать, однако подклассы i_BIS_Data<XX> с различными типами для XX несовместимы.

+1

+1. Вы избили меня на 16 секунд с помощью шаблона. Эта последняя проблема (не общие базовые классы) может быть исправлена ​​путем создания класса шаблона из некоторого класса без шаблона. –

+0

Это не позволяет ему использовать i_BIS_Data * для ссылки на любой из подтипов, поскольку изначально проблема заключалась в том, что все подтипы имели определение структуры дифференциала. Решение Дэвида, вероятно, так же хорошо, как и будет. –

+0

@WayneTanner: они НЕ являются подтипами, потому что они нарушают LSP. –

2

No.

В теории ООП, аргументы функции перегрузок могут быть контравариантны и тип возвращаемого значения может быть ковариантен.

В C++ допускается тип возвращаемого значения covariant, но типы параметров являются инвариантными.

То, о чем вы просите, это ковариация по типу аргумента, которая теоретически ошибочна, а также не допускается в C++.

Предлагаю вам ознакомиться с Принципом замещения Лискова. Это очень поможет, поскольку вы создаете иерархии классов с наследованием.

+0

Есть ли возможный способ определения УстановитьДанные максимально стандартизован, что все дети могут с пользой наследовать интерфейс? – Kat

+1

@Kat: Покажите, как вы ожидаете вызвать функцию, с учетом 'vector ' ... Когда вы попытаетесь это сделать, вы поймете, почему нет смысла включать эту функцию в состав интерфейса. –

+0

Я не планирую вызывать функцию i_BIS_Data - класс не может быть создан. Это дочерний класс, который должен содержать процедуру для выполнения функции. – Kat

1
class i_BIS_Data 
{ 
    public: 

    i_BIS_Data(void) { } 
    virtual ~i_BIS_Data(void) { } 

    virtual void setData(void* data) = 0; 
}; 


class BIS_0192_Aircraft_ID_Data : i_BIS_Data 
{ 
    public: 

    struct bis_data 
    { 
    UInt16 acid; 
    UInt16 parity; 
    }; 

    bis_data m_data; 

    void setData(void* data) 
    { 
     m_data = *(bis_data*)data; 
     // m_data.parity = data.parity; 
     // m_data.acid = data.acid; 
    } 
}; 

Пример:

BIS_0192_Aircraft_ID_Data::bis_data data; 

data.acid = 7; 
data.parity = 8; 

BIS_0192_Aircraft_ID_Data c; 

c.setData((void*)&data); 
+0

Спасибо. Если бы я не ответил выше, я бы использовал это решение. Я пытался держаться подальше от указателей пустоты. :) – Kat