473,396 Members | 1,836 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

Horrible include problem

I've asked about includes before in this group in order to
stop files being #included either twice or not at all, and
somebody said to use extern keyword for global variables
that need to be used in another cpp file, and to also put
all the includes of header files in the stdafx.h file, and
then to have every cpp file just include stdafx and
nothing else.
I've done this, so far with success.
However now I want to create a class A, that manages a
load of objects of type class B on the heap (using a
CTypedPtrList<CObList, ClassB*>, performing various
operations on them and then calling delete on them in its
constructor. However I want to have a variable in the
manager class that the objects can all reference,
consequently all the objects have to have a reference to
the manager class, which means they need to know its
definition. Thus, class A has to be able to 'see' class B,
and class B has to be able to 'see' class A, when
compiling. How do I arrange the include statements so that
it doesn't get either 'redefinition' or 'must have
class/struct/union type'?

Nov 16 '05 #1
6 1922
Searching google for "forward class declaration cpp" returned this:
http://www.eventhelix.com/RealtimeMa...dePatterns.htm
Hope that helps!
Elias
Nov 16 '05 #2
Ben Taylor wrote:

I've asked about includes before in this group in order to
stop files being #included either twice or not at all, and
somebody said to use extern keyword for global variables
that need to be used in another cpp file, and to also put
all the includes of header files in the stdafx.h file, and
then to have every cpp file just include stdafx and
nothing else.
I've done this, so far with success.


I see you got a good answer, but as an aside... If "somebody" said to
put all the includes in stdafx.h they did you a horrible disservice.
This gives you the exact opposite of object-oriented programming, and it
considerably slows down compilation time (i.e. your time) as well.
Includes are confusing when one is a newbie - but they (usually) become
easy once you understand the compiler's simple-minded needs.

--
Scott McPhillips [VC++ MVP]
Nov 16 '05 #3
Ben Taylor wrote:

I've asked about includes before in this group in order to
stop files being #included either twice or not at all, and
somebody said to use extern keyword for global variables
that need to be used in another cpp file, and to also put
all the includes of header files in the stdafx.h file, and
then to have every cpp file just include stdafx and
nothing else.


You should not put header includes that will change frequently in
stdafx.h. The whole point to it is to allow you to precompile the
headers that don't change, and that will be negated by putting
everything there.

(This is particularly important for the windows headers, which will
change only rarely. They're quite large and they take a significant
amount of time to process. By precompiling them, you realize a
substantial savings on every file you compile that incldues them.)

If you really want a more global include file, do one separately from
stdafx.h.

--
Craig Powers
MVP - Visual C++
Nov 16 '05 #4
Excellent, thanks. see response to Craig.

"Scott McPhillips" <sc******@mvps.org> wrote in message
news:3F***************@mvps.org...
Ben Taylor wrote:

I've asked about includes before in this group in order to
stop files being #included either twice or not at all, and
somebody said to use extern keyword for global variables
that need to be used in another cpp file, and to also put
all the includes of header files in the stdafx.h file, and
then to have every cpp file just include stdafx and
nothing else.
I've done this, so far with success.


I see you got a good answer, but as an aside... If "somebody" said to
put all the includes in stdafx.h they did you a horrible disservice.
This gives you the exact opposite of object-oriented programming, and it
considerably slows down compilation time (i.e. your time) as well.
Includes are confusing when one is a newbie - but they (usually) become
easy once you understand the compiler's simple-minded needs.

--
Scott McPhillips [VC++ MVP]

Nov 16 '05 #5
Yes, cheers Carl. That's essentially exactly what I did in a little test at
work today after seeing lallous's website, although here in your example
you've included ClassA.h and ClassB.h twice - once in each of ClassA.cpp and
ClassB.cpp - would that not cause it to throw a refefinition wobbly? Or do
you need inclusion guards, do these work for classes as well as #defines?
Also please see my response to Craig that I'm not exactly sure how msdev
decides what order the .cpp files should get compiled in.
"Carl Daniel [VC++ MVP]" <cp******@nospam.mvps.org> wrote in message
news:%2*****************@tk2msftngp13.phx.gbl...
Ben Taylor wrote:
I've asked about includes before in this group in order to
stop files being #included either twice or not at all, and
somebody said to use extern keyword for global variables
that need to be used in another cpp file, and to also put
all the includes of header files in the stdafx.h file, and
then to have every cpp file just include stdafx and
nothing else.
I've done this, so far with success.
However now I want to create a class A, that manages a
load of objects of type class B on the heap (using a
CTypedPtrList<CObList, ClassB*>, performing various
operations on them and then calling delete on them in its
constructor. However I want to have a variable in the
manager class that the objects can all reference,
consequently all the objects have to have a reference to
the manager class, which means they need to know its
definition. Thus, class A has to be able to 'see' class B,
and class B has to be able to 'see' class A, when
compiling. How do I arrange the include statements so that
it doesn't get either 'redefinition' or 'must have
class/struct/union type'?
Here's one common approach - where both classes have pointers to each

other:
//-----------------------
// ClassA.h

class B; // incomplete class

class A
{
CTypedPtrList<CObjList, B*> m_list;
};
// ClassB.h

class A; // incomplete class

class B
{
A* m_a;
};

// ClassA.cpp

#include "ClassA.h"
#include "ClassB.h"

// ... ClassA member functions

// ClassB.cpp

#include "ClassB.h"
#include "ClassA.h"

// ... ClassB member functions

//-----------------------

In general, if you have a set of classes that form a circular series of
dependencies, then at least one of those dependencies has to be by pointer
or reference. In C++ it's specifically legal to declare pointers to
incomplete (or "forward defined") classes in order to implement circular
dependencies such as you described.

-cd

Nov 16 '05 #6
It would be normal for both ClassA.cpp and ClassB.cpp to include both header
files: If ClassB is to call member functions on ClassA, then it has to see
the definition of ClassA. Similarly, if ClassA needs to call member
functions of ClassB (including the constructor), then it needs to see the
definition of ClassB.

This doesn't cause any multiple definition problems as long as you haven't
put inappropriate things (like non-inline function definitions) in the
header files.

The include files should have include guards, although nothing in my example
requires them: no .cpp file includes any .h file more than once.

As for the order of compilation, it's completely undefined, except that
"stdafx.cpp" (or whatever your PCH builder is named) is compiled first.
Since each file is compiled individually, the order of compilation has no
effect on the meaning or correctness of the program.

-cd

Ben Taylor wrote:
Yes, cheers Carl. That's essentially exactly what I did in a little
test at work today after seeing lallous's website, although here in
your example you've included ClassA.h and ClassB.h twice - once in
each of ClassA.cpp and ClassB.cpp - would that not cause it to throw
a refefinition wobbly? Or do you need inclusion guards, do these work
for classes as well as #defines? Also please see my response to Craig
that I'm not exactly sure how msdev decides what order the .cpp files
should get compiled in.
"Carl Daniel [VC++ MVP]" <cp******@nospam.mvps.org> wrote in message
news:%2*****************@tk2msftngp13.phx.gbl...
Ben Taylor wrote:
I've asked about includes before in this group in order to
stop files being #included either twice or not at all, and
somebody said to use extern keyword for global variables
that need to be used in another cpp file, and to also put
all the includes of header files in the stdafx.h file, and
then to have every cpp file just include stdafx and
nothing else.
I've done this, so far with success.
However now I want to create a class A, that manages a
load of objects of type class B on the heap (using a
CTypedPtrList<CObList, ClassB*>, performing various
operations on them and then calling delete on them in its
constructor. However I want to have a variable in the
manager class that the objects can all reference,
consequently all the objects have to have a reference to
the manager class, which means they need to know its
definition. Thus, class A has to be able to 'see' class B,
and class B has to be able to 'see' class A, when
compiling. How do I arrange the include statements so that
it doesn't get either 'redefinition' or 'must have
class/struct/union type'?


Here's one common approach - where both classes have pointers to
each other:

//-----------------------
// ClassA.h

class B; // incomplete class

class A
{
CTypedPtrList<CObjList, B*> m_list;
};
// ClassB.h

class A; // incomplete class

class B
{
A* m_a;
};

// ClassA.cpp

#include "ClassA.h"
#include "ClassB.h"

// ... ClassA member functions

// ClassB.cpp

#include "ClassB.h"
#include "ClassA.h"

// ... ClassB member functions

//-----------------------

In general, if you have a set of classes that form a circular series
of dependencies, then at least one of those dependencies has to be
by pointer or reference. In C++ it's specifically legal to declare
pointers to incomplete (or "forward defined") classes in order to
implement circular dependencies such as you described.

-cd

Nov 16 '05 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: Matthew | last post by:
Hi, I am working on a small project as well as trying to learn python. I parse a text file like def some_user_func(): # <name> Some user function #<description> The description pass
2
by: Stephen Thorne | last post by:
Hi, import re foo_pattern = re.compile('foo') '>>> m = foo_pattern.search(subject) '>>> if m: '>>> pass '>>> else: '>>> pass
140
by: Oliver Brausch | last post by:
Hello, have you ever heard about this MS-visual c compiler bug? look at the small prog: static int x=0; int bit32() { return ++x; }
2
by: andrew lowe | last post by:
Hi there, We have to use a com interop library generated by tlbimp, where the orginal com object is written in uniface (a compuware language). The method we use and have the problem with has the...
0
by: Hakuin | last post by:
Hello, I installed visual web developer 2005 express, and started to use it with mysql/odbc driver. It happens that when I open the database pane, and make some operations with the sql manager,...
5
by: Tio | last post by:
I have project in MFC(vc++) . There are files and classes: classes:dialog1,dialog2,aaa,bbb ---------------------- main.cpp --------------------- #include "mainfrm.h" #include "dialog1.h"...
10
by: JonathanOrlev | last post by:
Hello everybody, I wrote this comment in another message of mine, but decided to post it again as a standalone message. I think that Microsoft's Office 2003 help system is horrible, probably...
1
by: ilikewine | last post by:
The menu drop down icons (only the gray inactive icons) look horrible in Windows Classic Theme. Once they are active and have color, they look fine. If we switch to XP theme, they look just fine....
22
by: tenxian | last post by:
Could you put up with the horrible PHP code?
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
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,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
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...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.