inheritance issue

L

Luca

Suppose I have a base class that contains a private member that is a
pointer to an object whose type is a derived class:
**************************************************
// file base.h

#include "derived.h"

class Base {
Derived* derived;
public:
Base(Derived* derived);
. . .
};
**************************************************
**************************************************
// file derived.h

#include "derived.h"

class Derived : public Base {
. . .
};
**************************************************

this doesn't work; to have the things work properly I have to change
the file base.h like the following:

**************************************************
// file base.h

class Derived; <------------------- here is the change!
(instead of #include
"derived.h"

class Base {
Derived* derived;
public:
Base(Derived* derived);
. . .
};
**************************************************

Do you know why?
 
J

Josephine Schafer

Luca said:
Suppose I have a base class that contains a private member that is a
pointer to an object whose type is a derived class:
**************************************************
// file base.h

#include "derived.h"

class Base {
Derived* derived;
public:
Base(Derived* derived);
. . .
};
**************************************************
**************************************************
// file derived.h

#include "derived.h"

You meant #include "base.h" ??
class Derived : public Base {
. . .
};
**************************************************

this doesn't work; to have the things work properly I have to change
the file base.h like the following:

**************************************************
// file base.h

class Derived; <------------------- here is the change!
(instead of #include

The above is called a forward declarartion.
"derived.h"

class Base {
Derived* derived;
public:
Base(Derived* derived);
. . .
};
**************************************************

Do you know why?

You had made a cyclic inclusion of header files.
You are bound to get linker errors.
A forward declaration is enough when you are dealing with
pointers/references,
i.e. where the compiler can live without knowing the actual size of the
object.

HTH,
J.Schafer
 
D

David White

Luca said:
Suppose I have a base class that contains a private member that is a
pointer to an object whose type is a derived class:
**************************************************
// file base.h

#include "derived.h"

class Base {
Derived* derived;
public:
Base(Derived* derived);
. . .
};
**************************************************
**************************************************
// file derived.h

#include "derived.h"

Don't you mean:
#include "base.h"
?

The definition of class Base must come first if class Derived is to be
derived from it, so you have to include "base.h" first.
class Derived : public Base {
. . .
};
**************************************************

this doesn't work; to have the things work properly I have to change
the file base.h like the following:

**************************************************
// file base.h

class Derived; <------------------- here is the change!
(instead of #include

A forward declaration.
"derived.h"

class Base {
Derived* derived;

For a pointer or reference, the compiler only needs to know that Derived is
a class, but does not need to see its definition, so the forward declaration
is sufficient. However, where you actually use the pointer to access
Derived's members etc. (in another file), you will need to have included
"derived.h" first.
public:
Base(Derived* derived);
. . .
};
**************************************************

Do you know why?

Clearly, it's not going to work if "base.h" needs to include "derived.h"
first, but "derived.h" needs to include "base.h" first. So you need to do it
with the forward declaration.

DW
 
L

Luca

David White said:
Don't you mean:
#include "base.h"
?

The definition of class Base must come first if class Derived is to be
derived from it, so you have to include "base.h" first.


A forward declaration.


For a pointer or reference, the compiler only needs to know that Derived is
a class, but does not need to see its definition, so the forward declaration
is sufficient. However, where you actually use the pointer to access
Derived's members etc. (in another file), you will need to have included
"derived.h" first.


Clearly, it's not going to work if "base.h" needs to include "derived.h"
first, but "derived.h" needs to include "base.h" first. So you need to do it
with the forward declaration.

DW

sorry guys, here is the exact code:

///////////////////////////////////////////
// file base.h
///////////////////////////////////////////
#ifndef INC_BASE
#define INC_BASE

#include "derived.h"

class Base {
Derived* derived;
public:
Base(Derived* derived);
. . .
};

#endif /* INC_BASE */
///////////////////////////////////////////


///////////////////////////////////////////
// file derived.h
///////////////////////////////////////////
#ifndef INC_DERIVED
#define INC_DERIVED

#include "base.h"

class Derived : public Base {
. . .
};

#endif /* INC_DERIVED */
///////////////////////////////////////////

this code doesn't compile; I have to modify the line
#include "derived.h"
in file base.h to:
class Derived;

can you re-tell me why?
 
D

David White

Luca said:
"David White" <no.email@provided> wrote in message

sorry guys, here is the exact code:

///////////////////////////////////////////
// file base.h
///////////////////////////////////////////
#ifndef INC_BASE
#define INC_BASE

#include "derived.h"

class Base {
Derived* derived;
public:
Base(Derived* derived);
. . .
};

#endif /* INC_BASE */
///////////////////////////////////////////


///////////////////////////////////////////
// file derived.h
///////////////////////////////////////////
#ifndef INC_DERIVED
#define INC_DERIVED

#include "base.h"

class Derived : public Base {
. . .
};

#endif /* INC_DERIVED */
///////////////////////////////////////////

this code doesn't compile; I have to modify the line
#include "derived.h"
in file base.h to:
class Derived;

can you re-tell me why?

The reason is the same one given. In the version that doesn't compile, Base
can't be compiled without the definition for Derived, and Derived can't be
compiled without the definition for Base. It's a catch-22. Why do think it
should be okay?

DW
 
L

Luca

David White said:
The reason is the same one given. In the version that doesn't compile, Base
can't be compiled without the definition for Derived, and Derived can't be
compiled without the definition for Base. It's a catch-22. Why do think it
should be okay?

DW

Ok, now I've understood the problem. In Italy we say "it's like a cat
that's trying to bite his tail"

Thank you

Luca
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,141
Messages
2,570,817
Members
47,362
Latest member
ChandaWagn

Latest Threads

Top