dynamic_cast и поле

198
04 января 2018, 23:37

Возник такой вопрос у меня есть map <string, WarShip *> где WarShip это указатель на экземпляр класса, WarShip это класс всех допустим кораблей в котором наследуются ромбовидно 3 корабля других,но каждый корабль имеет своё отличие, и поле которым он отличается, как мне через dynamic_cast обратится к этому полю, определённого корабля в map ? Вот к примеру я знаю что это авианосец ибо в нём есть поля которые указывают на наличие мест для самолётов, а в крейсере этого поля нету, но мне нужно допустим изменить наличие мест(модифицировать) как мне обратится к этому полю ?

Вот допустим я добавляю корабль

MainGroup.TableCarryGroup.insert(
    pair<string, WarShip *>(CALLSIGN, 
                            new Cruiser(HP,SPD,SCF,givenWeapon,
                                        QOCM,givenHuman,NAME_SHIP,IACarryShip,
                                        MainGroup.countCAPS,MainGroup.countWEA‌​PONS))); 

Далее мне нужно вернуть всю информацию об этом корабле, но Cruiser - наследник WarShip. Имеет своё специфическое поле под названием string InfoAboutCarryShip.

if(SHIP->type_ship == 1)
{ 
    Cruiser *cruiser = dynamic_cast<Cruiser*>(SHIP); 
    cout << "16.Information about carrying ship"
         << cruiser->infoAboutCarryShip << endl; 
} 

вот таким образом я хочу вывести данное поле что я делаю не правильно?

при использовании static_cast выдало такую ошибку:

error: cannot convert from pointer to base class 'warship::WarShip' to pointer to derived class 'cruiser::Cruiser' because the base is virtual Cruiser *cruiser = static_cast(SHIP);

Answer 1

Ну, допустим, что этот авианосец - Carrier - наследник WarShip. А w - указатель на WarShip, сохраненный в вашем map.

Carrier * c = dynamic_cast<Carrier*>(w);
if (c) // На тот случай, если это не авианосец
{
    c->getPlanes(); // Или что там вам надо...
}

Примерно так. Понятно, что должен быть включен RTTI, а у WarShip быть виртуальные функции...

Update
Раз вы храните поле типа корабля (не нравится мне ваш дизайн... но хозяин - барин...) - то приводите с помощью static_cast:

if(SHIP->type_ship == 1)
{ 
    Cruiser *cruiser = static_cast<Cruiser*>(SHIP); 
    cout << "16.Information about carrying ship"
         << cruiser->infoAboutCarryShip << endl; 
}
Answer 2

Во-первых, dynamic_cast для выполнения downcast применим только к полиморфным типам. Ваш тип WarShip - полиморфен? Если нет, то никакой dynamic_cast тут не применим.

Во-вторых, если вы действительно "точно знаете", какой тип имеет данный объект, то задачу решит static_cast. У него нет требования полиморфности. Но и проверку правильности приведения (как это делает dynamic_cast) он выполнить не может, так что тут вы должны делать downcast на свой страх и риск. Также static_cast не сможет сделать downcast через виртуальное наследование, если оно вдруг у вас есть.

В-третьих, если тип все-таки полиморфен, то может быть вопрос можно решить без приведения типа вообще? Ваш вопрос обладает гигантским потенциалом быть XY-проблемой: вы пытаетесь выяснить, как выполнить downcast, чтобы доступиться к полю класса-наследника, хотя на самом деле полиморфизм для того и предназначен, чтобы вам этого не нужно было делать.

В вашем случае (настолько, насколько его можно понять из приведенной вами информации), класс корабля сам должен уметь выдавать информацию о себе в предоставленный поток при помощи какого-то виртуального метода

class WarShip 
{
  ...
  virtual void WriteSpecificInfo(std::ostream &strm) = 0;
  ...
};
class Cruiser : public WarShip
{
  ...
  virtual void WriteSpecificInfo(std::ostream &strm) override
  {
    strm << "16.Information about carrying ship" << infoAboutCarryShip;
  }
  ...
};
...
SHIP->WriteSpecificInfo(std::cout);
std::cout << std::endl;

И никаких if (SHIP->type_ship == 1) и приведений.

READ ALSO
Изменение значение индекса в map

Изменение значение индекса в map

Как поменять значение индекса в mapС обычным значением понятно, обращаться через индекс

230
Отображение MapPolyline на карте QML. C++/Qt

Отображение MapPolyline на карте QML. C++/Qt

По заданию необходимо отобразить карту на экране и рисовать на ней линииПробую сделать вот так:

186
Функция шаблон в классе

Функция шаблон в классе

Есть класс автобусЕсть после destination (маршрут который проходит) petrol (количество бензина потраченного)

167
Как загрузить xml из ресурсов для Jsoup

Как загрузить xml из ресурсов для Jsoup

Как это можно сделать? Метод parse() принимает String

207