Средства копирования атрибутов производного класса без динамического приведения

Я пытаюсь найти эффективный способ (используя полиморфизм) для копирования определенных атрибутов между двумя производными классами извне. У меня есть набор классов данных, которые являются производными от базового класса DataClassA, Я хочу работать с этими классами данных в отдельном классе фильтра, который принимает DataClassA ссылки в качестве входных и выходных параметров. Фильтр выполнит необходимые операции, общие для DataClassA, но я также хочу распространять специфичные для класса атрибуты из моего ввода в выходной класс. Рассматривать:

class DataClassA
{
public:
virtual void copyAttributes( DataClassA& copyFrom );
}

class DataClassB : public DataClassA
{
public:
virtual void copyAttributes( DataClassA& copyFrom );
};

class DataFilter
{
void run( DataClassA& input, DataClassB& output )
{
//do some calculations here
...
//then copy over attributes
output.copyAttributes( input );
}
};

Моя проблема, очевидно, в том, что copyAttributes() зависит от необходимости знать типы входных и выходных производных классов (которые не обязательно должны быть одинаковыми). Однако фильтр будет обрабатывать только ссылки на базовый класс. DataClassA, Мой рефлекс просто установить dynamic_castхотя я рискую получить пощечину (и другие возможные негативные последствия). Если бы я сделал это, я бы просто создал copyAttributes метод для каждого производного класса, который называется copyAttributes родительского класса, а затем использовать dynamic_cast чтобы увидеть, если copyFrom Объект того же типа:

void DataClassB::copyAttributes( DataClassA& copyFrom )
{
//copy attributes from parent class
DataClassA::copyAttributes( copyFrom );

//test if the class being copied from is of type DataClassB
DataClassB* copyPtr = dynamic_cast<DataClassB*>&copyFrom;
if( copyPtr != NULL )
{
//copy DataClassB-specific attributes from copyFrom to this
...
}
}

Наиболее похожий пост, который я смог найти по этой проблеме, был здесь Виртуальные функции и полиморфизм. Мои основные вопросы: 1) не подходит ли мое предполагаемое использование dynamic_cast ?; и 2) если так, как я мог бы реализовать это copyAttributes по-другому? Были ссылки на использование шаблона дизайна посетителя, хотя я не уверен, как это будет выглядеть.

Это своего рода более простая версия того, что делает Visualization Toolkit (VTK) в том смысле, что я использую классы фильтров, которые работают с рядом различных классов данных. Интересно, что они обрабатывают RTTI, включая макросы, которые включают в себя строковое имя классов и родительские классы, которые можно сравнивать напрямую для правильного уменьшения типов данных.

1

Решение

Кажется, вы хотите multi-dispatch (как это я сделал здесь: https://ideone.com/8VxALs)
Это требует, чтобы посетитель знал каждый производные типы.

Другой подход заключается в использовании dynamic_cast каждый раз.

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

class DataClassA
{
public:
virtual ~A() {}
virtual void copyAttributes(DataClassA& copyFrom) { copyFrom.copyAttributesToA(*this); }
virtual void copyAttributesToA(DataClassA& copyTo) { /* Implementation to copy A -> A */ }
virtual void copyAttributesToB(DataClassB& copyTo) { /* Implementation to copy A -> B */ }
};

class DataClassB : public DataClassA
{
public:
void copyAttributes(DataClassA& copyFrom) override { copyFrom.copyAttributesToB(*this); }
void copyAttributesToA(DataClassA& copyTo) override { /* Implementation to copy B -> A */ }
void copyAttributesToB(DataClassB& copyTo) override { /* Implementation to copy B -> B */ }
};
0

Другие решения


По вопросам рекламы [email protected]