Movatterモバイル変換


[0]ホーム

URL:


CodeQL documentation
CodeQL resources

Virtual call from constructor or destructor

ID: cpp/virtual-call-in-constructorKind: problemSecurity severity: Severity: warningPrecision: highTags:   - reliability   - readability   - language-features   - external/jsfQuery suites:   - cpp-security-and-quality.qls

Click to see the query in the CodeQL repository

This rule finds calls to virtual functions from a constructor or destructor that may resolve to a different function than was intended. When instantiating a derived class, the resolution of a virtual function call depends on the type that defines the constructor/destructorthat is currently running, not the class that is being instantiated. This is to prevent the calling of functions in the derived class that rely on fields declared in the derived class. The values of such fields are undefined until the constructor of the derived class is invokedafter the constructor of the base class. Values declared in the derived class are likewise destructedprior to invocation of the destructor of the base class.

The indicated function call is a call to a virtual function in a constructor or destructor, which will most likely not call the intended function, or if correct would be difficult to interpret without knowledge of the class’ inheritance graph.

Recommendation

Do not call virtual functions from the constructor or destructor. Change the virtual function in the base into a non-virtual function and pass any required parameters from the derived classes, or simply perform initialization that requires a virtual function after construction/before destruction.

Example

classBase{protected:Resource*resource;public:virtualvoidinit(){resource=createResource();}virtualvoidrelease(){freeResource(resource);}};classDerived:publicBase{virtualvoidinit(){resource=createResourceV2();}virtualvoidrelease(){freeResourceV2(resource);}};Base::Base(){this->init();}Base::~Base(){this->release();}intf(){// this will call Base::Base() and then Derived::Derived(), but this->init()// inBase::Base() will resolve to Base::init(), not Derived::init()// The reason for this is that when Base::Base is called, the object being// created is still of type Base (including the vtable)Derived*d=newDerived();}

References


[8]ページ先頭

©2009-2025 Movatter.jp