473,406 Members | 2,769 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,406 software developers and data experts.

Cannot compile simple example

Mtk
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;
}
Oct 10 '05 #1
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 -

Oct 10 '05 #2
"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

Oct 10 '05 #3
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
Oct 10 '05 #4
Mtk
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

Oct 10 '05 #5
Mtk
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

Oct 10 '05 #6
"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

Oct 10 '05 #7
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!"
Oct 10 '05 #8
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
Oct 10 '05 #9
Mtk
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

Oct 10 '05 #10
Mtk
But, top-posting IS the right thing to do ;)

Artie Gold wrote:
[snip]
[top posting corrected]

[snip]
Oct 10 '05 #11
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!"
Oct 10 '05 #12
Mtk schrieb:
But, top-posting IS the right thing to do ;)


Read this:

http://www.netmeister.org/news/learn2quote2.html#ss2.3

And after that, the rest of the text.

Thomas
Oct 10 '05 #13

"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.
Oct 11 '05 #14

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

Similar topics

8
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...
1
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...
8
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 -------------------------------------------------------------------------------- ...
2
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...
10
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...
10
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...
5
by: wong_powah | last post by:
#include <vector> #include <iostream> using std::cout; using std::vector; enum {DATASIZE = 20}; typedef unsigned char data_t;
45
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...
17
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...
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: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
marktang
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,...
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
jinu1996
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...
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...
0
agi2029
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,...

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.