Hi!
Why does the following, simple, example produce such errors?
I know it has to do with the two header files including each other and
(moreover) the usage of the classes One and Two in the "opposite" header
file... What do I have to do to make this example work?
Thanks for all the help!
// * Error messages:
One.h(11): error C2146: syntax error : missing ';' before identifier 't'
One.h(11): error C2501: 'One::Two' : missing storage-class or type
specifiers
One.h(11): error C2501: 'One::t' : missing storage-class or type specifiers
Two.h(11): error C2146: syntax error : missing ';' before identifier 't'
// * File One.h
#ifndef ONE_H
#define ONE_H
#include "Two.h"
class One
{
public:
One();
private:
Two t;
};
#endif
// * File One.cpp
#include "One.h"
One::One()
{
}
// * File Two.h
#ifndef TWO_H
#define TWO_H
#include "One.h"
class Two
{
public:
Two();
private:
One t;
};
#endif
// * File Two.cpp
#include "Two.h"
Two::Two()
{
}
// * File Main.cpp
int main()
{
return 0;
} 13 1631
I'm new to this, too. So bear with me.
But your header files are CIRCULAR.
one defines the other. Walk through line by line and there is great
confusion.
You must straighten out the sequence of instructions so there is NO
ambiguity. Then it looks like it should compile ok.
- Robert -
"Mtk" <sp***********@nra.org> wrote in message
news:di**********@news.island.liu.se... Why does the following, simple, example produce such errors? I know it has to do with the two header files including each other
Because of the "include guards," the two files only look like including each
other. In effect, one of them includes the other one; and that's it. (Second
one includes the first one too, but at that time the body of the first
header is included as nothing.)
and (moreover) the usage of the classes One and Two in the "opposite" header file... What do I have to do to make this example work?
You have to use a forward declaration and must use one of the classes as
reference (meaning both reference and pointer) in the other header.
// * Error messages: One.h(11): error C2146: syntax error : missing ';' before identifier 't' One.h(11): error C2501: 'One::Two' : missing storage-class or type specifiers One.h(11): error C2501: 'One::t' : missing storage-class or type specifiers Two.h(11): error C2146: syntax error : missing ';' before identifier 't'
// * File One.h #ifndef ONE_H #define ONE_H
#include "Two.h"
class One { public: One(); private: Two t;
That line is good; because we know what Two is.
};
#endif
// * File One.cpp #include "One.h"
One::One() { }
// * File Two.h #ifndef TWO_H #define TWO_H
#include "One.h"
The line above is ineffective, because the macro ONE_H is defined at this
point, so what we include with the line above is "nothing."
class Two { public: Two(); private: One t;
You have a conceptual problem on the line above. It is not possible to have
two objects include each other; that would be infinite recursively.
At least one of your classes must "refer" to the other one; it should not
include it as a part.
};
#endif
Without knowing your exact requirements, here is one solution:
Don't include "One.h" in Two.h; instead, forward declare One. Then, keep a
reference to a One object in Two, don't contain one:
// * File Two.h
#ifndef TWO_H
#define TWO_H
class One; // <-- Forward declaration
class Two
{
public:
explicit Two(One & one) // <-- Take a reference
:
t(one) // <-- Remember your One
{}
private:
One & t; // <-- Keep a reference
};
#endif
By the way, I think this must be an FAQ.
Ali
Mtk wrote: Why does the following, simple, example produce such errors? I know it has to do with the two header files including each other and (moreover) the usage of the classes One and Two in the "opposite" header file... What do I have to do to make this example work?
You can't.
Let's condense your example to one file. And let's suppose the compiler
knows about classes 'One' and 'Two' somehow _apriori_.
[...] class One { public: One(); private: Two t; }; [...] class Two { public: Two(); private: One t; };
Now, what is the size of a class One object? As soon as you can come up
with a formula the compiler can use to calculate it, let us know.
Meanwhile, look up "forward declaration".
V
Thanks for the reply.
I may be a newbie when it comes to c++, but there must be a simpler
solution to my problem than the one you described.
Not including "One.h" in "Two.h", and attempting to forward-declare
class One, gives the error message "Two.h(10): error C2079: 'Two::t'
uses undefined class 'One'" - of course.
Anyway. I'll take a look at forward declarations.
Thanks again
Ali Çehreli wrote:
[huge snip] Without knowing your exact requirements, here is one solution:
Don't include "One.h" in Two.h; instead, forward declare One. Then, keep a reference to a One object in Two, don't contain one:
// * File Two.h #ifndef TWO_H #define TWO_H
class One; // <-- Forward declaration
class Two { public: explicit Two(One & one) // <-- Take a reference : t(one) // <-- Remember your One {}
private: One & t; // <-- Keep a reference
};
#endif
By the way, I think this must be an FAQ.
Ali
Hi!
I forgot to mention that I'm a newbie and I have no intention to make
the compiler calculate the size of any class at all (at least for now)
and, thus, I'll skip that part.
I just want class One to have a variable of the "class Two"-type and
vice-versa, giving the requirement that each class is located in its own
header file.
I'll look "forward declarations" up.
Thanks
Victor Bazarov wrote: Mtk wrote: Why does the following, simple, example produce such errors? I know it has to do with the two header files including each other and (moreover) the usage of the classes One and Two in the "opposite" header file... What do I have to do to make this example work?
You can't.
Let's condense your example to one file. And let's suppose the compiler knows about classes 'One' and 'Two' somehow _apriori_.
> [...] class One { public: One(); private: Two t; }; > [...] class Two { public: Two(); private: One t; };
Now, what is the size of a class One object? As soon as you can come up with a formula the compiler can use to calculate it, let us know.
Meanwhile, look up "forward declaration".
V
"Mtk" <sp***********@nra.org> wrote in message
news:di**********@news.island.liu.se... Thanks for the reply.
I may be a newbie when it comes to c++, but there must be a simpler solution to my problem than the one you described.
There isn't a simpler solution. We must break the circular dependency
somehow.
Not including "One.h" in "Two.h", and attempting to forward-declare class One, gives the error message "Two.h(10): error C2079: 'Two::t' uses undefined class 'One'" - of course.
Did you make Two::t a reference? (See my code below.)
Anyway. I'll take a look at forward declarations.
Here is an excellent read: http://www.gotw.ca/gotw/007.htm
Check out the rest of the GotW archive as well :)
[...] // * File Two.h #ifndef TWO_H #define TWO_H
class One; // <-- Forward declaration
class Two { public: explicit Two(One & one) // <-- Take a reference : t(one) // <-- Remember your One {}
private: One & t; // <-- Keep a reference
};
Ali
Mtk wrote: Victor Bazarov wrote:
Mtk wrote:
Why does the following, simple, example produce such errors? I know it has to do with the two header files including each other and (moreover) the usage of the classes One and Two in the "opposite" header file... What do I have to do to make this example work?
You can't.
Let's condense your example to one file. And let's suppose the compiler knows about classes 'One' and 'Two' somehow _apriori_.
> [...]
class One { public: One(); private: Two t; };
> [...]
class Two { public: Two(); private: One t; };
Now, what is the size of a class One object? As soon as you can come up with a formula the compiler can use to calculate it, let us know.
Meanwhile, look up "forward declaration".
V
[top posting corrected] Hi!
I forgot to mention that I'm a newbie and I have no intention to make the compiler calculate the size of any class at all (at least for now) and, thus, I'll skip that part.
That's not a good idea; understanding this is *absolutely central* to
your understanding of why you can't do what you're trying to do.
I just want class One to have a variable of the "class Two"-type and vice-versa, giving the requirement that each class is located in its own header file.
Right. See above. I'll look "forward declarations" up.
HTH,
--ag
--
Artie Gold -- Austin, Texas http://goldsays.blogspot.com (new post 8/5) http://www.cafepress.com/goldsays
"If you have nothing to hide, you're not trying!"
On Mon, 10 Oct 2005 21:08:18 +0200, Mtk wrote: I just want class One to have a variable of the "class Two"-type and vice-versa, giving the requirement that each class is located in its own header file.
But then a "One" object (which contains a "Two" object containing a "One"
object) would then, within itself, contain another complete One object.
Which contains a Two which contains a One which...
The only way this can make sense is if a One object is of infinite size.
- Jay
Thanks!
I'm reading on ;)
Ali Çehreli wrote: "Mtk" <sp***********@nra.org> wrote in message news:di**********@news.island.liu.se... Thanks for the reply.
I may be a newbie when it comes to c++, but there must be a simpler solution to my problem than the one you described.
There isn't a simpler solution. We must break the circular dependency somehow.
Not including "One.h" in "Two.h", and attempting to forward-declare class One, gives the error message "Two.h(10): error C2079: 'Two::t' uses undefined class 'One'" - of course.
Did you make Two::t a reference? (See my code below.)
Anyway. I'll take a look at forward declarations.
Here is an excellent read:
http://www.gotw.ca/gotw/007.htm
Check out the rest of the GotW archive as well :)
[...]
// * File Two.h #ifndef TWO_H #define TWO_H
class One; // <-- Forward declaration
class Two { public: explicit Two(One & one) // <-- Take a reference : t(one) // <-- Remember your One {}
private: One & t; // <-- Keep a reference
};
Ali
But, top-posting IS the right thing to do ;)
Artie Gold wrote:
[snip] [top posting corrected]
[snip]
Mtk wrote: But, top-posting IS the right thing to do ;)
Artie Gold wrote: [snip]
[top posting corrected]
[snip]
In which case you've revealed yourself as a troll, thereby not worthy of
further attention. Of course, like all good trolls, you'll probably morph.
Great.
--ag
--
Artie Gold -- Austin, Texas http://goldsays.blogspot.com (new post 8/5) http://www.cafepress.com/goldsays
"If you have nothing to hide, you're not trying!"
"Mtk" <sp***********@nra.org> wrote in message
news:di**********@news.island.liu.se... Hi!
I forgot to mention that I'm a newbie and I have no intention to make the compiler calculate the size of any class at all (at least for now) and, thus, I'll skip that part.
I just want class One to have a variable of the "class Two"-type and vice-versa, giving the requirement that each class is located in its own header file.
I'll look "forward declarations" up.
Thanks
Think about this a second. You want class One to include class two, and
class two to include class One. Lets look at it in a tree type way:
class One <-- class instance
class Two <-- includes class
class One <--- includes class
class Two <-- includes class
class One <-- includes class...
you see the problem? It goes on forever.
The solution? Keep a pointer or reference to the other class. A pointer or
reference is of a fixed size, no matter the size of the object it points to.
So now we have:
class One <-- class instance
class* Two <-- includes class pointer
and that's it. And class two now looks like:
class Two <-- class instance
class* One <-- includes class pointer
Now, you may be tempted to do something like this:
class Two;
class One
{
public:
One() { TwoPoint = new Two; }
private:
Two* TwoPoint;
};
class Two
{
public:
Two() { OnePoint = new One; }
private:
One* OnePoint;
};
But that won't work either, becuase now you've just moved the recursion from
compile time to run time. See, when you create your instance of class One
it calls the constructor for class two which creates and instance of class
One which calls the constructor for class two which...
You need to rethink your design and determine what it is you actually need. This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: janeaustine50 |
last post by:
Python's InteractiveInterpreter uses the built-in compile function.
According to the ref. manual, it doesn't seem to concern about the
encoding of the source string.
When I hand in an unicode...
|
by: Tony Johansson |
last post by:
Hello!
I get compile error when compiling using the command javac from the command
terminal window(CMD).
I have just two classes which are called HelloWorld.java and Slask.java.
I have both...
|
by: baustin75 |
last post by:
Posted: Mon Oct 03, 2005 1:41 pm Post subject: cannot mail() in ie
only when debugging in php designer 2005
--------------------------------------------------------------------------------
...
|
by: PeterW |
last post by:
I have an xml file from which I want to generate an xsd schema and at a later
stage a cs class.
The xml file has a mix of defined namespaces and also an empty namespace.
These are defined as...
|
by: Jean-David Beyer |
last post by:
I have some programs running on Red Hat Linux 7.3 working with IBM DB2
V6.1 (with all the FixPacks) on my old machine.
I have just installed IBM DB2 V8.1 on this (new) machine running Red Hat...
|
by: Bart Goeman |
last post by:
Hi,
I have a question about how to put redundant information in data
structures, initialized at compile time. This is often necessary
for performance reasons and can't be done at run time (data...
|
by: wong_powah |
last post by:
#include <vector>
#include <iostream>
using std::cout;
using std::vector;
enum {DATASIZE = 20};
typedef unsigned char data_t;
|
by: Zytan |
last post by:
This returns the following error:
"Cannot modify the return value of
'System.Collections.Generic.List<MyStruct>.this' because it is
not a variable"
and I have no idea why! Do lists return copies...
|
by: fl |
last post by:
Hi,
I am learning C++ from the following C++ website, which has some very
good small examples. For the second Fraction example, which has five
files:
Main.cpp
Fraction.cpp
Fraction.h...
|
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
|
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...
|
by: nemocccc |
last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
|
by: marktang |
last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
|
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...
|
by: jinu1996 |
last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
|
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...
|
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: 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,...
| |