By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
458,110 Members | 1,543 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 458,110 IT Pros & Developers. It's quick & easy.

What's the rule for using forward declarations?

P: n/a
I'm hoping someone can please help me remember the C++ rule: When
you're writing a header file for a class (say, some_namespace::Bar),
and that class makes use of another class (some_namespace::Foo),

-------------------------------- snip --------------------------------
#ifndef GUARD_Foo_HPP
#define GUARD_Foo_HPP

namespace some_namespace {

class Foo
{
// Stuff.
};

} // namespace some_namespace.

#endif // GUARD_Bar_HPP
-------------------------------- snip --------------------------------
you have the option of either #including Foo.hpp,
-------------------------------- snip --------------------------------
#ifndef GUARD_Bar_HPP
#define GUARD_Bar_HPP

#include Foo.hpp

namespace some_namespace {

class Bar
{
// Stuff -- some of which uses Foo's.
};

} // namespace some_namespace.

#endif // GUARD_Bar_HPP
-------------------------------- snip --------------------------------

or else just making a forward declaration:

-------------------------------- snip --------------------------------
#ifndef GUARD_Bar_HPP
#define GUARD_Bar_HPP

namespace some_namespace {

// NOTE: We're *inside* the namespace declaration for this:
class Foo;

class Bar
{
// Stuff -- some of which uses Foo's.
};

} // namespace some_namespace.

#endif // GUARD_Bar_HPP
-------------------------------- snip --------------------------------

I realize that using the forward declaration is always preferable
(so as to make fewer dependencies, as well as less work for the
preprocessor and compiler), but what's the rule for when I can get
away with it?

Thanks.
--
--- remove zees if contacting via email ---

Jul 22 '05 #1
Share this Question
Share on Google+
5 Replies


P: n/a
John Gabriele wrote:
I'm hoping someone can please help me remember the C++ rule: When
you're writing a header file for a class (say, some_namespace::Bar),
and that class makes use of another class (some_namespace::Foo),

-------------------------------- snip --------------------------------
#ifndef GUARD_Foo_HPP
#define GUARD_Foo_HPP

namespace some_namespace {

class Foo
{
// Stuff.
};

} // namespace some_namespace.

#endif // GUARD_Bar_HPP
-------------------------------- snip --------------------------------
you have the option of either #including Foo.hpp,
-------------------------------- snip --------------------------------
#ifndef GUARD_Bar_HPP
#define GUARD_Bar_HPP

#include Foo.hpp

namespace some_namespace {

class Bar
{
// Stuff -- some of which uses Foo's.
};

} // namespace some_namespace.

#endif // GUARD_Bar_HPP
-------------------------------- snip --------------------------------

or else just making a forward declaration:

-------------------------------- snip --------------------------------
#ifndef GUARD_Bar_HPP
#define GUARD_Bar_HPP

namespace some_namespace {

// NOTE: We're *inside* the namespace declaration for this:
class Foo;

class Bar
{
// Stuff -- some of which uses Foo's.
};

} // namespace some_namespace.

#endif // GUARD_Bar_HPP
-------------------------------- snip --------------------------------

I realize that using the forward declaration is always preferable
(so as to make fewer dependencies, as well as less work for the
preprocessor and compiler), but what's the rule for when I can get
away with it?

Thanks.

Basically you can get away with it as long as you only have pointers and
references in your header. If you have declarations of user defined types
(insted of pointers or references to them), because of the rules for
instantiating these types where they are declared, the compiler has to have
the full definition of the type available in order to allocate memory.
Does this make sense?
--
"[M]y dislike for the preprocessor is well known. Cpp is essential in C
programming, and still important in conventional C++ implementations, but
it is a hack, and so are most of the techniques that rely on it. ...I think
the time has come to be serious about macro-free C++ programming." - B. S.

Jul 22 '05 #2

P: n/a
"John Gabriele" <jo*****@bestwebz.net> wrote in message
news:10*************@corp.supernews.com...
<snip>
or else just making a forward declaration:

-------------------------------- snip --------------------------------
#ifndef GUARD_Bar_HPP
#define GUARD_Bar_HPP

namespace some_namespace {

// NOTE: We're *inside* the namespace declaration for this:
class Foo;

class Bar
{
// Stuff -- some of which uses Foo's.
};

} // namespace some_namespace.

#endif // GUARD_Bar_HPP
-------------------------------- snip --------------------------------

I realize that using the forward declaration is always preferable
(so as to make fewer dependencies, as well as less work for the
preprocessor and compiler), but what's the rule for when I can get
away with it?


You can "get away" with a forward declaration when the code that relies on
it is using the type "in name only". That basically means that the code
doesn't need to know the size of the type or the members of the type. This
generally occurs when the type is only being passed around by
pointer/reference. For example, suppose the following was inline inside
your "Bar" class definition:

void foo( Foo* p ) { // OK
p->memfun(); // error
}

void foo2() {
Foo f; // error
}

The FAQ (http://www.parashift.com/c++-faq-lite/) talks about forward
declarations a bit in section 38 ("Miscellaneous technical issues")
questions 11 through 14.

--
David Hilsee
Jul 22 '05 #3

P: n/a
David Hilsee wrote:
"John Gabriele" <jo*****@bestwebz.net> wrote in message
news:10*************@corp.supernews.com...
<snip>
or else just making a forward declaration:

-------------------------------- snip --------------------------------
#ifndef GUARD_Bar_HPP
#define GUARD_Bar_HPP

namespace some_namespace {

// NOTE: We're *inside* the namespace declaration for this:
class Foo;

class Bar
{
// Stuff -- some of which uses Foo's.
};

} // namespace some_namespace.

#endif // GUARD_Bar_HPP
-------------------------------- snip --------------------------------

I realize that using the forward declaration is always preferable
(so as to make fewer dependencies, as well as less work for the
preprocessor and compiler), but what's the rule for when I can get
away with it?

You can "get away" with a forward declaration when the code that relies on
it is using the type "in name only". That basically means that the code
doesn't need to know the size of the type or the members of the type. This
generally occurs when the type is only being passed around by
pointer/reference. For example, suppose the following was inline inside
your "Bar" class definition:

void foo( Foo* p ) { // OK
p->memfun(); // error
}

void foo2() {
Foo f; // error
}

The FAQ (http://www.parashift.com/c++-faq-lite/) talks about forward
declarations a bit in section 38 ("Miscellaneous technical issues")
questions 11 through 14.


Ahh. Thanks Dave (and also Steve). That makes sense.

Also, thanks for the link to the faq. I just dug out my
old dead-tree version, but it looks like there's been many
updates to it since publication in 1999. :)

---J

--
--- remove zees if contacting via email ---

Jul 22 '05 #4

P: n/a

"David Hilsee" <da*************@yahoo.com> wrote in message
news:E7********************@comcast.com...
"John Gabriele" <jo*****@bestwebz.net> wrote in message
news:10*************@corp.supernews.com...
<snip>
or else just making a forward declaration:

-------------------------------- snip --------------------------------
#ifndef GUARD_Bar_HPP
#define GUARD_Bar_HPP

namespace some_namespace {

// NOTE: We're *inside* the namespace declaration for this:
class Foo;

class Bar
{
// Stuff -- some of which uses Foo's.
};

} // namespace some_namespace.

#endif // GUARD_Bar_HPP
-------------------------------- snip --------------------------------

I realize that using the forward declaration is always preferable
(so as to make fewer dependencies, as well as less work for the
preprocessor and compiler), but what's the rule for when I can get
away with it?
You can "get away" with a forward declaration when the code that relies on
it is using the type "in name only".


-snip -
void foo( Foo* p ) { // OK
p->memfun(); // error
}


Pardon my ignorance, but when would someone use a type by "name only"? To me
it seems useless to forward declare a class when its member
functions/variables are inaccessable.
Jul 22 '05 #5

P: n/a
"Method Man" <a@b.c> wrote in message
news:K8******************@read1.cgocable.net...
<snip>
void foo( Foo* p ) { // OK
p->memfun(); // error
}

Pardon my ignorance, but when would someone use a type by "name only"? To

me it seems useless to forward declare a class when its member
functions/variables are inaccessable.


The FAQ has a good example where it is necessary to use forward declarations
in question 38.11 (referenced in my other post). They are also useful for
eliminating compilation dependencies, which is what John Gabriele seems to
be doing. This is the logic behind the pimpl idiom
(http://www.gotw.ca/gotw/024.htm). If you can forward declare a class in a
header instead of defining it in the header, then you won't have to
recompile as many source files when the definition of that class changes. I
have also used "opaque pointers" in C to provide a bit of encapsulation.
One module provided a forward declaration for a type that is used as a
"handle" to something that it didn't want other modules modifying or
depending upon its representation. To do anything with it, the other
modules had to pass the handle to the module that provided it.

--
David Hilsee
Jul 22 '05 #6

This discussion thread is closed

Replies have been disabled for this discussion.