IssueConversion or deletion of incomplete class pointer occurs
      when you delete or cast to a pointer to an incomplete class. An incomplete class is one whose
      definition is not visible at the point where the class is used.
For instance, the definition of class
            Body is not visible when the delete operator is
          called on a pointer to
          Body:
class Handle {
  class Body *impl;  
public:
  ~Handle() { delete impl; }
  // ...
};
 RiskWhen you delete a pointer to an incomplete class, it is not possible to call any
        nontrivial destructor that the class might have. If the destructor performs cleanup
        activities such as memory deallocation, these activities do not happen.
A similar problem happens, for instance, when you downcast to a pointer to an incomplete
        class (downcasting is casting from a pointer to a base class to a pointer to a derived
        class). At the point of downcasting, the relationship between the base and derived class is
        not known. In particular, if the derived class inherits from multiple classes, at the point
        of downcasting, this information is not available. The downcasting cannot make the necessary
        adjustments for multiple inheritance and the resulting pointer cannot be
        dereferenced.
A similar statement can be made for upcasting (casting from a pointer to derived class
        to a pointer to a base class).
 FixWhen you delete or downcast to a pointer to a class, make sure that the class definition
        is visible.
Alternatively, you can perform one of these actions:
- Instead of a regular pointer, use the - std::shared_ptrtype to
              point to the incomplete class.
 
- When downcasting, make sure that the result is valid. Write error-handling code
              for invalid results. 
 Example - Deletion of Pointer to Incomplete Classclass Handle {
  class Body *impl;  
public:
  ~Handle() { delete impl; } //Noncompliant
  // ...
};
In this example, the definition of class Body is not visible when the
        pointer to Body is deleted.
 Correction — Define Class Before DeletionOne possible correction is to make sure that the class definition is visible when a
          pointer to the class is deleted.
class Handle {
  class Body *impl;  
public:
  ~Handle();
  // ...
};
 
// Elsewhere
class Body { /* ... */ };
  
Handle::~Handle() {
  delete impl;
}
 Correction — Use std::shared_ptrAnother possible correction is to use the std::shared_ptr type
          instead of a regular pointer.
#include <memory>
  
class Handle {
  std::shared_ptr<class Body> impl;
  public:
    Handle();
    ~Handle() {}
    // ...
};
 Example - Downcasting to Pointer to Incomplete ClassFile1.h:
class Base {
protected:
  double var;
public:
  Base() : var(1.0) {}
  virtual void do_something();
  virtual ~Base();
};
File2.h:
void funcprint(class Derived *);
class Base *get_derived(); 
File1.cpp:
#include "File1.h"
#include "File2.h"
 
void getandprint() {
  Base *v = get_derived();
  funcprint(reinterpret_cast<class Derived *>(v)); //Noncompliant
}
File2.cpp:
#include "File2.h"
#include "File1.h"
#include <iostream>
 
class Base2 {
protected:
  short var2;
public:
  Base2() : var2(12) {}
};
 
class Derived : public Base2, public Base {
  float var_derived;
public:
    Derived() : Base2(), Base(), var_derived(1.2f) {}
    void do_something()
    {
        std::cout << "var_derived: "
                  << var_derived << ", var : " << var
                  << ", var2: " << var2 << std::endl;
    }
 };
 
void funcprint(Derived *d) {
  d->do_something();
}
 
Base *get_derived() {
  return new Derived;
}
In this example, the definition of class Derived is not visible in
          File1.cpp when a Base* pointer to downcast to a
          Derived* pointer.
In File2.cpp, class Derived derives from two
        classes, Base and Base2. This information about
        multiple inheritance is not available at the point of downcasting in
          File1.cpp. The result of downcasting is passed to the function
          funcprint and dereferenced in the body of funcprint.
        Because the downcasting was done with incomplete information, the dereference can be
        invalid.
 Correction — Define Class Before DowncastingOne possible correction is to define the class Derived before
          downcasting a Base* pointer to a Derived*
          pointer.
In this corrected example, the downcasting is done in File2.cpp in
          the body of funcprint at a point where the definition of class
            Derived is visible. The downcasting is not done in
            File1.cpp where the definition of Derived is not
          visible. The changes from the previous incorrect example are highlighted.
File1_corr.h:
class Base {
protected:
  double var;
public:
  Base() : var(1.0) {}
  virtual void do_something();
  virtual ~Base();
};
File2_corr.h:
void funcprint(class Base *);
class Base *get_derived(); 
File1.cpp:
#include "File1_corr.h"
#include "File2_corr.h"
 
void getandprint() {
  Base *v = get_derived();
  funcprint(v);
}
File2.cpp:
#include "File2_corr.h"
#include "File1_corr.h"
#include <iostream>
 
class Base2 {
protected:
  short var2;
public:
  Base2() : var2(12) {}
};
 
class Derived : public Base2, public Base {
  float var_derived;
public:
    Derived() : Base2(), Base(), var_derived(1.2f) {}
    void do_something()
    {
        std::cout << "var_derived: "
                  << var_derived << ", var : " << var
                  << ", var2: " << var2 << std::endl;
    }
};
 
void funcprint(Base *d) {
  Derived *temp = dynamic_cast<Derived*>(d);
  if(temp)  {
     d->do_something();
  }
  else {
      //Handle error
  }
}
 
Base *get_derived() {
  return new Derived;
}