Мы используем куки, чтобы пользоваться сайтом было удобно.
Хорошо
to the top
>
>
>
Тонкость с виртуальными функциями

Тонкость с виртуальными функциями

11 Янв 2010

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

В анализаторе Viva64 есть диагностика ошибок, возникающих в 64-битном коде, когда у виртуальных функций изменяется тип аргумента. Подробнее это описано в документации к продукту здесь: V301.

Вот пример кода, где анализатор выдаст эти предупреждения:

class A
{
public:
  virtual int x(unsigned) { return 1; }
  virtual int y(__int64) { return 2; }
};
class B : public A
{
public:
  int x(size_t) { return 3; } //V301
  int y(ptrdiff_t) { return 4; } //V301
};
void Use()
{
  A *p = new B;
  cout <<p->x(1) << " " <<p->y(1) << endl;
  delete p;
}

В 32-битном режиме на печать будет выдано "3 2", а в 64-битном режиме "1 4". Ошибки в данном коде успешно диагностируются анализатором Viva64. Но недавно меня посетила мысль, что необходимо диагностировать не только изменяющиеся аргументы виртуальных функций, но и возвращаемый аргумент. В голове у меня возник следующий пример, который следует диагностировать как ошибочный:

class A
{
public:
  virtual int x() {};
};
class B : public A
{
public:
  ptrdiff_t x() {};
};

К счастью такой вариант в 64-битном режиме просто не скомпилируется и соответственно не возникнет ошибки связанной с изменением поведения кода. Компилятор Visual C++ выдает ошибку:

error C2555: 'B::x': overriding virtual function return type differs and is not covariant from 'A::x' : see declaration of 'A::x'

После проделанного эксперимента, я начал припоминать, что, кажется, уже проделывал подобное исследование. И соответственно диагностика по возвращаемым значениям не требуется. Подумав, я решил сделать эту запись в блог, чтобы через год в третий раз не вернуться к этому вопросу. :)

Рассмотрим последний момент, связанный с диагностикой функций, где отличается как аргумент, так и возвращаемый тип:

class A
{
public:
  virtual int x(int) { return 1; }
};
class B : public A
{
public:
  ptrdiff_t x(ptrdiff_t) { return 2; } //V301
};

Данный код компилируется и содержит ошибку. Анализатор Viva64 корректно разбирается в подобной ситуации и предупреждает, что аргумент изменяет свой тип в 64-битной системе. После исправления этой ошибки, компилятор откажется компилировать код и будет исправлена вторая ошибка - тип возвращаемого аргумента.

Популярные статьи по теме


Комментарии (0)

Следующие комментарии next comments
close comment form
close form

Заполните форму в два простых шага ниже:

Ваши контактные данные:

Шаг 1
Поздравляем! У вас есть промокод!

Тип желаемой лицензии:

Шаг 2
Team license
Enterprise license
** Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности
close form
Запросите информацию о ценах
Новая лицензия
Продление лицензии
--Выберите валюту--
USD
EUR
RUB
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

close form
Бесплатная лицензия PVS‑Studio для специалистов Microsoft MVP
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

close form
Для получения лицензии для вашего открытого
проекта заполните, пожалуйста, эту форму
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

close form
Мне интересно попробовать плагин на:
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

close form
check circle
Ваше сообщение отправлено.

Мы ответим вам на


Если вы так и не получили ответ, пожалуйста, проверьте, отфильтровано ли письмо в одну из следующих стандартных папок:

  • Промоакции
  • Оповещения
  • Спам