views:

178

answers:

2

I was happily working in C++, until compilation time arrived.

I've got several classes inside some namespace (let's call it N); two of these classes correspond to one base class, and other derived from it. Each class has its own pair of .hpp and .cpp files; I think it'd look like:

namespace N{

    class Base{
    };

    class Derived: public Base{
    };

}

However, g++ (maybe linker) keeps telling me:

Derived.hpp:n: error: expected class-name before ‘{’ token

It doesn't recognize Base as a class, even when I have correctly #include'ed the hpp file corresponding to its definition to Derived's .hpp!

"It's something with #includes", I thought, since these classes' .hpps are #included in other files, so I added this to Derived declaration in Derived.hpp:

#include "Base.hpp"
namespace N{

    class Base;

    class Derived: public Base{
    };
}

And now g++ complains:

Derived.hpp:n: error: invalid use of incomplete type ‘struct N::Base’

So, I got lost here. Please help me, I will apreciate it a lot. :)

(By the way, I'm rather experienced in Python, not C++, so this issues are really strange to me. Also, I changed classes' names and stuff :).

Edit: A more exact representation of my files is:

File Pieza.hpp
-----------------------
#include "Celda.hpp"

namespace Reglas
{
    class Pieza
    {    
        public:
        Pieza() {}
        virtual ~Pieza() {}

        private: 
        Celda *c; 
    };
}


File Jugador.hpp
-----------------------
#include "Jugada.hpp" 
#include "Excepciones.hpp"
#include "Pieza.hpp"
namespace Reglas
{  
//compiler asked for these :S
class Celda;
class Tablero;
    class Jugador : public Pieza
    {
        public:
        Jugador() {}
        virtual ~Jugador() {}
    };
}
+3  A: 

Your files should look like:

File Base.hpp
-----------------------
namespace N
{
    class Base
    {    
        public:
        Base() {}
        virtual ~Base() {}   // Make sure you have a virtual destructor
    };
}


File Derived.hpp
-----------------------
#include "Base.hpp"
namespace N
{  
    class Derived : public Base
    {
        public:
        Derived() {}
        ~Derived() {}
    };
}
RC
@mmyers - Thanks for correcting my grammar.
RC
No problem - hope my edit summary doesn't come off as condescending. I do that so that non-native speakers can learn from their mistakes rather than having to rely on editors all the time.
Michael Myers
+3  A: 
Derived.hpp:n: error: invalid use of incomplete type ‘struct N::Base’

This makes me think that you didn't #include "Base.hpp in the Derived.cpp source file.

EDIT: In your Derived.cpp, try changing the order of #includes to:

#include "base.hpp"
#include "derived.hpp"

// .. rest of your code ..

Like this:

// Derived.hpp
#pragma once

namespace foo
{
    class Base;

    class Derived : public Base
    {
    public:
        Derived();

        ~Derived();
    };
}

// Derived.cpp
#include "base.hpp"
#include "derived.hpp"

namespace foo
{
    Derived::Derived()
    {
    }

    Derived::~Derived()
    {
    }
}

So, you're going to want to edit Jugador.hpp to look like this:

// Jugador.hpp
#include "Pieza.hpp" // move this above Jugada.hpp
#include "Jugada.hpp" 
#include "Excepciones.hpp"
namespace Reglas
{  
//compiler asked for these :S
class Celda;
class Tablero;
    class Jugador : public Pieza
    {
        public:
        Jugador() {}
        virtual ~Jugador() {}
    };
}
kitchen
Or the includes are out of order, which is more likely here.
Joshua
I did included it :(
Fabzter
I've updated my answer, hopefully it helps.
kitchen
Ok, I mark your answer as the corect one. A brief explanation: Pieza.hpp contained the definition of class Pieza, which contained a member of class Celda. that's why I included Celda.hpp in Pieza.hpp. However, Class Celda has a member of class Jugador (derived from Pieza!!!), so Celda.hpp includes Jugador.hpp, which itself includes Pieza.hpp (*sigh*). So when the compiler was preprocessing the first includes in Pieza.hpp, it ended up again in Pieza.hpp, before being able to define class Pieza, so Jugador could never inherit from it. So, as you suggested, i #included Celda.hpp in Pieza.cpp.
Fabzter