Ожидаемая эквивалентность: typeid выражения данных и выражения типа

66
10

У меня есть полиморфные классы, полученные из базового класса A:

class A {
public:
virtual void fV() { }
};

class B : public A {
public:
void mB() { }
};

class C : public A {
public:
void mC() { }
};

Теперь я хочу перебрать массив, указывающий на такие объекты, и проверить эквивалентность типа:

A *array[4] = { new B, new C, new C, new B };
for(int i = 0; i < 4; ++i) {
cout << i + 1 << ". " ;
(typeid(array[i]) == typeid(A)) ? cout << 1 << ' ': cout << 0 << ' ';
(typeid(*array[i]) == typeid(B)) ? cout << 1 << ' ': cout << 0 << ' ';
(typeid(*array[i]) == typeid(C)) ? cout << 1 << ' ': cout << 0 << ' ';
cout << endl;
}

Результат:

1. 0 1 0 
2. 0 0 1
3. 0 0 1
4. 0 1 0

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

Что не так с первым условием?

спросил(а) 2021-01-19T19:01:03+03:00 9 месяцев назад
1
Решение
111

Ваш массив определяется как A* array[4]. Таким образом, тип array[i] будет A*.

Следовательно, для второго столбца (первый столбец после индекса):

    typeid(array[i]) == typeid(A) всегда будет ложным (то есть 0 во втором столбце) typeid(array[i]) == typeid(A*) всегда будет истинным (т.е. 1 во втором столбце) typeid(*array[i]) == typeid(A) может быть правдой, если в вашем массиве появился новый элемент A.

Онлайн-демо для третьего случая, заменив один из производного объекта на объект A.

Внимание. Типовая эквивалентность, которую вы проверяете, является строгой эквивалентностью типа. Это верно только для точных совпадений. Это означает, что для второго столбца тест завершится неудачно для объекта, полученного из B. Возможно, это то, что вы ищете и хорошо. Но это серьезно ограничило бы расширяемость вашего полиморфного дизайна, если вы намерены просто проверить, нужно ли вызывать mB() или mC(). В качестве альтернативы вы можете рассмотреть возможность использования dynamic_cast<> и проверки того, возвращает ли он nullptr или нет

ответил(а) 2021-01-19T19:01:03+03:00 9 месяцев назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема