主要内容

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

An object's dynamic type shall not be used from the body of its constructor or destructor

Description

Rule Definition

An object's dynamic type shall not be used from the body of its constructor or destructor.1

Rationale

The dynamic type of an object is the type of its most derived class. For instance:

struct B { 
	virtual ~B() {}
}; 
struct D: B {}; 
D d; 
B* ptr = &d;
The dynamic type of the object pointed to by *ptr is D because that is the most derived class in the polymorphic hierarchy.

When you invoke the dynamic type of a polymorphic object in its constructor or destructor, you might get the type of the constructed or destroyed object instead of the type of the most derived object. This is because when you invoke the dynamic type during construction or destructor, the derived classes might not be constructed yet. Using dynamic types in constructors and destructors might result in unexpected behavior. Calling pure virtual functions from constructors and destructors results in undefined behavior. Avoid using the dynamic type of an object in its constructors or destructors.

Polyspace Implementation

Polyspace® flags these items when they are used in a constructor or a destructor of a polymorphic class:

  • The operator typeid.

  • Virtual or pure virtual functions that are not invoked using a member of the class.

  • The function dynamic_cast or implicit C-style casts.

Polyspace assumes that a class is polymorphic if it has any virtual member.

Troubleshooting

If you expect a rule violation but Polyspace does not report it, see Diagnose Why Coding Standard Violations Do Not Appear as Expected.

Examples

expand all

#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                   
	}
};

In this example, class PS has no virtual member. Polyspace does not consider PS a polymorphic class. Because PS is not polymorphic, its dynamic type does not change at run time. Polyspace does not flag using the typeid operator in the constructor PS::PS().

PS_1 is considered polymorphic because it has a virtual member function. Because it is polymorphic, its dynamic type changes during run time. Polyspace flags the invocation of its dynamic type in the constructor PS_1::PS_1().

In this example, the class Derived inherits from the class Base. The class hierarchy is polymorphic because the base class contains the virtual function, which is overridden in the derived class. The destructor of Base calls the virtual function virtualFunction(). Calling a virtual function in the destructor is reported a violation. In the destructor of Derived, virtualFunction() is invoked using a class member, which is not reported as a violation.

#include <iostream>

// Base class
class Base {
public:
	Base() {
		std::cout << "Base constructor called." << std::endl;
	}

	virtual ~Base() {
		std::cout << "Base destructor called." << std::endl;
		// Call the virtual function
		virtualFunction();  // Noncompliant
	}

	virtual void virtualFunction() const {
		std::cout << "Base virtual function." << std::endl;
	}
};

// Derived class
class Derived : public Base {
private:
	Base *BaseObj;
public:

	Derived() {
		BaseObj =  new Base();
		std::cout << "Derived constructor called." << std::endl;
	}

	~Derived() override {
		std::cout << "Derived destructor called." << std::endl;
		BaseObj->virtualFunction();  //Compliant
		delete BaseObj;
	}

	void virtualFunction() const override {
		std::cout << "Derived virtual function." << std::endl;
	}

};

Check Information

Group: Special Member Functions
Category: Required

Version History

Introduced in R2013b

expand all


1 All MISRA coding rules and directives are © Copyright The MISRA Consortium Limited 2021.

The MISRA coding standards referenced in the Polyspace Bug Finder™ documentation are from the following MISRA standards:

  • MISRA C:2004

  • MISRA C:2012

  • MISRA C:2023

  • MISRA C++:2008

  • MISRA C++:2023

MISRA and MISRA C are registered trademarks of The MISRA Consortium Limited 2021.