Неверное преобразование типов с использованием static_cast, какое правильное приведение я должен использовать?

У меня есть определение типа typedef vector<Object*> ObjList; У меня тоже есть функция vector<BigObject*>* ObjectBox::getBigObjectList();, BigObject наследуется от Object

То, что я хотел сделать, это получить vector<BigObject*>* от getBigObjectList() и преобразовать его в vector<Object*>*, который является восходящим приведением, и этот тип определяется как ObjList так что я в основном хотел превратить это в ObjList тип

Я пробовал два способа, первый

ObjList *normalObjectList = (ObjList*) box->getBigObjectList();

Это компилируется и я читаю из этой статьи (Когда следует использовать static_cast, dynamic_cast, const_cast и reinterpret_cast?) который говорит, что кастинг в стиле C редко желателен, так как его можно превратить в reinterpret-cast

Тогда я пытаюсь использовать static_cast, но я получил сообщение об ошибке: неверное преобразование типов

ObjList *normalObjectList = static_cast<ObjList*> (box->ClipObjectInRect());

Также это не сработает

ObjList *normalObjectList = static_cast<vector<Object*>*> (box->ClipObjectInRect());

Почему это не работает? Это потому что static_cast может использоваться только для приведения прямого класса (например, Object сам по себе) вместо вложенного (я тут просто догадываюсь)? Что мне делать в этом случае?

1

Решение

У ваших рассуждений есть очень обычный недостаток; Я думаю, что все мы когда-то сделали одну и ту же ошибку. Вы думаете о std::vector<> как просто выходной контейнер, потому что именно так вы хотите использовать его сейчас, но это не так.

Просто представьте, что следующий код будет компилироваться:

vector<BigObject*>* bigVector = box->ClipObjectInRect(); // OK
ObjList* objVector = static_cast<ObjList*>(bigVector);   // Not OK; we'll now see why
objVector->push_back(new SmallObject()); // OUCH

Как вы можете видеть, разрешение этого броска позволит вам попытаться SmallObject* в чем может содержаться только BigObject*, Это наверняка приведет к ошибке во время выполнения.

Кстати, вы можете на самом деле приводить между массивами связанных типов. Это поведение, унаследованное от C. И это приводит к ошибкам во время выполнения 🙂

3

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

Статическое приведение также не будет выполнено, если компилятор не знает (или делает вид, что не знает) об отношениях между типами. Если ваше наследство не объявлено общественности между ними компилятор будет рассматривать их как несвязанные типы и выдает одно и то же загадочное предупреждение.

Это просто укусило меня, так что я поделился.

12

Я могу ошибаться, но я думаю, что вам может потребоваться привести каждый отдельный объект в вектор. Я бы попытался перегрузить getBigObjectList (), чтобы вернуть ObjList *. Таким образом, ваша перегруженная функция будет выглядеть примерно так

ObjList* ObjectBox::getBigObjectList()
{
vector<Object*> return_vec
for(vector<BigObject*>::iterator itr = ObjectBox.bigObjectList.begin(); itr != ObjectBox.bigObjectList.end(); itr++)
{
return_vec.push_back(static_cast<Object*> (itr));
}
return return_vec
}

По какой-то конкретной причине вы описываете свой вектор в виде списка? Или используя вектор вместо списка?

РЕДАКТИРОВАТЬ: В основном то, что сказал Денис.

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