You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 9 Next »

Non-Compliant Code Example

Consider a design that attempts to seize and release an object's resources through calls to virtual functions from a base class's constructor and destructor.

class B {
  public:
    B() { seize(); }
    virtual ~B() { release(); }
  protected:
    virtual void seize() {}
    virtual void release() {}
};

class D : public B {
  public:
    D() {}
    ~D() {}
  protected:
    void seize() {
        B::seize();
        // get derived resources...
    }
    void release() {
        // release derived resources...
        B::release();
    }
};

D x;

The result of running this code is that no derived class resources will be seized or released during the initialization and destruction of the x object. At the time of the call to seize in the initialization of x, the D constructor has not been entered, and the behavior of the under-construction x object will be to invoke B::seize rather than D::seize. A similar situation occurs for the call to release in the base class destructor. If the functions seize and release were declared to be pure virtual functions, the result would be undefined behavior.

Compliant Solution

Avoid calling an object's virtual functions while it is being constructed or destroyed.

class B {
  public:
    B() {
        // seize base resources...
    }
    virtual ~B() {
        // release base resources...
    }
};

class D : public B {
  public:
    D() {
        // seize derived resources...
    }
    ~D() {
        // release derived resources...
    }
};

D x;

Note that it is perfectly legitimate to call virtual functions of other, fully constructed objects from a constructor or destructor.

Risk Assessment

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

OBJ30-CPP

1 (low)

1 (unlikely)

2 (medium)

P2

L3

References

[[Dewhurst 03]] Gotcha 75: Calling Virtual Functions in Constructors and Destructors
[[Sutter 04]] Item 49: Avoid calling virtual functions in constructors and destructors.


OBJ06-CPP. Create a copy constructor and assignment operator for non copyable objects      13. Object Orientation (OBJ)      OBJ33-CPP. Do not slice polymorphic objects

  • No labels