2016-07-21 7 views
1

Я предполагаю, что это классика, но в моем случае у меня есть ограничения, которые должны упростить проблему.C++: Расширить объект путем downcasting до производного класса

Просто я получаю некоторую структуру А на входе моего модуля и хочу добавить к нему несколько атрибутов. Поэтому я создаю структуру B, которая расширяет A и добавляет то, что мне нужно.

Теперь, когда я вызываю метод, ожидающий B, но я его подаю, компилятор не доволен: объекты не могут быть Bs, как и все кошки - не львы.

Но в моем случае я клянусь, что все как Bs, хотя и с меньшими атрибутами. Атрибуты, которые не найдены, могут быть представлены как неинициализированные, это прекрасно, я также клянусь, что никогда не буду вызывать атрибут перед его инициализацией. В основном, первое, что я делаю, когда вы получаете объекты A в качестве входных данных, это заполнить оставшиеся атрибуты B, которые вычисляются на основе атрибутов A. Я просто не хочу делать копии «Как я попадаю в Bs» только для добавления нескольких атрибутов, потому что тогда атрибуты As будут скопированы в память. Я не собираюсь когда-либо модифицировать эти исходные атрибуты A либо, я просто собираюсь использовать их для вычисления производных атрибутов, а затем переходить и работать с объектами B с атрибутами A и производными атрибутами.

Пример:

От общего, проекта шириной заголовка:

struct Rectangle { 
    // Side lengths 
    int a,b; 
} 

Из локального заголовка:

struct LocalRectangle : Rectangle { 
    int area; 
} 

void updateModule(Rectangle inputRect); 

От местного источника:

void updateModule(Rectangle inputRect) { 
    LocalRectangle r = (LocalRectangle)inputRect; 
    r.area = r.a*r.b; 
    // More processing ... 
} 

Как я сделай это ?

Спасибо заранее,

Чарльз

+0

Не могли бы вы отправить код? –

+0

Возможно, вы могли бы добавить поле к структуре As типа 'std :: map', которое будет содержать разные атрибуты и удалить структуры Bs, будучи все типа A. – LoPiTaL

+0

Можете ли вы изменить' A'? – Motti

ответ

1

Если вы можете изменить A-структуру можно рассматривать просто добавить эти значения в A с неинициализированным значением (с помощью указателя или boost::optional) и инициализировать их лениво.

В противном случае, если вы не можете изменить A и не хотите, чтобы скопировать значения из каждого A в этом соответствующих B вы можете рассмотреть вопрос о Bне проистекают из A, просто дополнительных атрибутов. Затем вы будете поддерживать глобальный std::map<A*, B>[1] и найти дополнительные атрибуты, просмотрев карту. Если вы выберете этот путь, спросите себя, знаете ли вы, когда нужно удалить устаревшее A s из map.


  1. Я использую A*, так как вы хотите, чтобы избежать копирования A с.
1

Если A является B с несколькими меньшими атрибутами, то это не B это? В противном случае мы сможем отбросить с любого объекта в мире на любой другой объект и просто искать атрибуты/методы, которые имеют одинаковые имена/подписи.

Но я должен был бы задать вопрос, почему вы хотели бы передать объект, который, как вы знаете, не соответствует типу. Если для метода не нужны дополнительные атрибуты, предоставленные B, измените его подпись, чтобы взять A *, а не B *. И если для этого нужны эти значения, вы не можете передать объект, который их не имеет.

Если вы действительно действительно должны это сделать, и я думаю, что вы видите, что я не вижу, что это хороший дизайн, тогда, возможно, подумайте о том, чтобы сделать статический метод где-нибудь, который берет A, и возвращает новый B с неизвестные атрибуты, установленные на нуль или что-то еще.

 Смежные вопросы

  • Нет связанных вопросов^_^