MISRA C++:2008 Rule 12-1-1

Динамический тип объекта не должен использоваться от тела его конструктора или деструктора

Описание

Управляйте определением

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

Объяснение

Динамический тип объекта является типом своей большей части производного класса. Например:

struct B { 
	virtual ~B() {}
}; 
struct D: B {}; 
D d; 
B* ptr = &d;
На динамический тип объекта указывает *ptr D потому что это - большая часть производного класса в полиморфной иерархии.

Когда вы вызываете динамический тип полиморфного объекта в его конструкторе или деструкторе, вы можете получить тип созданного или уничтоженного объекта вместо типа большей части производного объекта. Это вызвано тем, что, когда вы вызываете динамический тип во время конструкции или деструктора, производные классы еще не могут быть созданы. Используя динамические типы в конструкторах и деструкторах может привести к неожиданному поведению. Вызывание чистых виртуальных функций от конструкторов и деструкторов приводит к неопределенному поведению. Избегайте использования динамического типа объекта в его конструкторах или деструкторах.

Реализация Polyspace

Polyspace® флаги эти элементы, когда они используются в конструкторе или деструкторе полиморфного класса:

  • Оператор typeid

  • Виртуальные или чистые виртуальные функции

  • Функциональный dynamic_cast или неявные броски C-стиля

Polyspace принимает, что класс является полиморфным, если это имеет какой-либо виртуальный член.

Поиск и устранение проблем

Если вы ожидаете нарушение правила, но не видите его, относитесь, чтобы Диагностировать, Почему Кодирующие Стандартные Нарушения Не Появляются как ожидалось.

Примеры

развернуть все

#include <cassert>
#include <typeinfo>

class PS
{
public:
	PS ( )
	{
		typeid ( PS );                // Compliant
	}
};

class PS_1
{
public:
	virtual ~PS_1 ( );
	virtual void bar ( );
	PS_1 ( )
	{
		typeid ( PS_1 );                // Noncompliant                   
		PS_1::bar ( );                  // Compliant 
		bar ( );                      // Noncompliant                   
		dynamic_cast< PS_1* > ( this ); // Noncompliant                   
	}
};

В этом примере, класс PS не имеет никакого виртуального члена. Polyspace не рассматривает PS полиморфный класс. Поскольку PS не является полиморфным, его динамический тип не изменяется во время выполнения. Polyspace не отмечает использование typeid оператор в конструкторе PS::PS().

PS_1 рассматривается полиморфным, потому что это имеет virtual функция членства. Поскольку это полиморфно, его динамические изменения типа в течение времени выполнения. Polyspace отмечает вызов своего динамического типа в конструкторе PS_1::PS_1().

Проверяйте информацию

Группа: специальные функции членства
Категория: необходимый
Введенный в R2013b