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 --- 5 1872
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.
"John Gabriele" <jo*****@bestwe bz.net> wrote in message
news:10******** *****@corp.supe rnews.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 ("Miscellane ous technical issues")
questions 11 through 14.
--
David Hilsee
David Hilsee wrote: "John Gabriele" <jo*****@bestwe bz.net> wrote in message news:10******** *****@corp.supe rnews.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 preprocesso r 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 ("Miscellane ous 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 ---
"David Hilsee" <da************ *@yahoo.com> wrote in message
news:E7******** ************@co mcast.com... "John Gabriele" <jo*****@bestwe bz.net> wrote in message news:10******** *****@corp.supe rnews.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.
"Method Man" <a@b.c> wrote in message
news:K8******** **********@read 1.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 This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics |
by: mjm |
last post by:
Folks,
Please help me with the following problems:
********************************************
1. I have a class template
template<class Base> class Matrix : public Base { /* .... */ }
|
by: Michael |
last post by:
Ok, I'm just checking i'm on the right lines:
sorry if i make a mistake with any strict definitions of things
in a .h , try and put:
class declaration (prototype)
relevant forward declarations for pointers in the class,
#includes required for the objects aggregated in the class
#includes required for base-classes
#includes for templates
|
by: Neil Cerutti |
last post by:
In Rob Pike's style guide he urges the following:
Simple rule: include files should never include include
files. If instead they state (in comments or implicitly)
what files they need to have included first, the problem of
deciding which files to include is pushed to the user
(programmer) but in a way that's easy to handle and that,
by construction, avoids multiple inclusions.
I was startled by this guideline, since...
|
by: Steve |
last post by:
Can anyone explain why C++ .NET compiler throws error for the following code
segment:
// Forward declaration of ListViewItemComparer class
public __gc class ListViewItemComparer ;
public __gc class CProgramLoaderForm : public System::Windows::Forms::Form
{
ListViewItemComparer* m_ListViewItemComparer ;
|
by: Neo |
last post by:
Hi,
I am new to C++ and want to know what are forward declarations and any
site which has a good introductory explanation.
thanks in advance,
nick
| |
by: fox |
last post by:
How do I (portably) make a forward reference to a static (I mean
file-scope) variable?
I've been using "extern" for years, for example:
extern int x;
int foo(void)
{
return x++;
}
|
by: Carlos Martinez Garcia |
last post by:
Hi all:
I usually make forward declarations in headers. Something like this:
class MyClass;
Now, I need a reference to a type defined like this (traditional C Style):
typedef struct {
|
by: The Cool Giraffe |
last post by:
One thing i do know for sure. When one creates a CPP file,
one needs to include the H file. Now, having said that, i
wonder if there are some general hints, requirements or
standard guide lines on what and how to include.
Suppose that we have a project consisting of a number of
classes and structs. Some of them using the others, some
using all of them. What is a good approach when including?
--
|
by: Rune Allnor |
last post by:
Hi all.
I have these classes, implemented as templates in header files.
Right now I have one file per class, where both the declarations
and implementations of one class are located in each file.
I would like to apply the visitor pattern to some of these classes.
One of the technicalities behind the visitor pattern is that one
needs forward declarations of classes, since there are two
class hierarchies which refer to each other.
|
by: Oralloy |
last post by:
Hello folks,
I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>".
The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed.
This is as boiled down as I can make it.
Here is my compilation command:
g++-12 -std=c++20 -Wnarrowing bit_field.cpp
Here is the code in...
|
by: tracyyun |
last post by:
Dear forum friends,
With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
| |
by: agi2029 |
last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own....
Now, this would greatly impact the work of software developers. The idea...
|
by: isladogs |
last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM).
In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules.
He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms.
Adolph will...
|
by: conductexam |
last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one.
At the time of converting from word file to html my equations which are in the word document file was convert into image.
Globals.ThisAddIn.Application.ActiveDocument.Select();...
|
by: TSSRALBI |
last post by:
Hello
I'm a network technician in training and I need your help.
I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs.
The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols.
I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
|
by: 6302768590 |
last post by:
Hai team
i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
|
by: muto222 |
last post by:
How can i add a mobile payment intergratation into php mysql website.
| |
by: bsmnconsultancy |
last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...
| |