-1
class C1
{
   public:
   C1* A;

   void SomeMethod()
   {
       class C2;
       C2* c2 = dynamic_cast<C2*>(A);
    }
};

class C2 : public C1 {};

In gcc i'm getting "target is not a pointer or reference to complete type" when dynamic_cast is invoked. What's wrong?

  • 1
    class C2 is not yet defined... – jsantander Jun 12 '14 at 14:23
  • put the statement `class C2;` before you define `class C1` – Iosif Murariu Jun 12 '14 at 14:26
  • 1
    Putting it before the definition won't change anything. – Jules Bianqi Jun 12 '14 at 14:28
  • @IosifMurariu: It will still be incomplete if you do that. The definition of `C2` needs to come before the `dynamic_cast`. (And since it must come after the definition of `C1` in order to inherit from it, the function body will have to be moved out of the class definition). – Mike Seymour Jun 12 '14 at 14:28
  • 3
    You'll also need to make `C1` polymorphic (i.e. give it at least one virtual function) for `dynamic_cast` to work. Better still, if possible, try to do whatever you're doing using a virtual function rather than a downcast. – Mike Seymour Jun 12 '14 at 14:32

2 Answers2

2

The following compiles:

class C2;

class C1
{
   virtual ~C1() { } // <--- NOTE MUST BE polymorphic to use dynamic_cast
   public:
   C1* A;

   void SomeMethod();
};

class C2 : public C1 {};

void C1::SomeMethod()
{
       C2* c2 = dynamic_cast<C2*>(A); // <=== USED after C2 definition 
}

int main() {

}

Two problems:

  1. C2 was only forward declared, thus an incomplete type (need complete declaration of the class)
  2. C1 was not polymorphic (dynamic_cast only applies to polymorphic types)
jsantander
  • 4,972
  • 16
  • 27
  • Yeah, thanks, that works fine. Actually that was just a simple example, my original "C1" class is polymorphic and much larger, so i don't need to artifically add a virtual function to make things work. – Jules Bianqi Jun 12 '14 at 14:45
0
class C2;
C2* c2 = dynamic_cast<C2*>(A);

The first line tells the compiler "There is a class type "C2" and it will be fully defined later in the compilation unit, when you find the definition".

If you try to use C2 instances as anything more than reference or pointer declarations (until the definition of the class is required), you will get an error telling you the pointer is not to a type that is fully defined ("or "complete type" in compilese language).

To fix:

#include <C2.h> // header where "class C2 { ... };" is defined

// no longer necessary: class C2;
C2* c2 = dynamic_cast<C2*>(A); // this should now compile
utnapistim
  • 26,809
  • 3
  • 46
  • 82