Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How to solve this problem?

8 views
Skip to first unread message

Hooyoo

unread,
Nov 20, 2006, 9:20:27 PM11/20/06
to
Following are similar codes of my project:
At first I define two classes in two files:
//ClassA.h
#pragma once
#include "ClassB.h"

class ClassA
{
public:
ClassA(void){};
public:
~ClassA(void){};
};

//ClassB.h
#pragma once
#include "ClassA.h"

class ClassA;

class ClassB
{
public:
ClassB(void){};
public:
~ClassB(void){};
void DoSomething(ClassA obj){};
};


Then main function:
//main.cpp
#include "ClassB.h"

int main(void)
{
return 0;
}

When I complie these codes in VS2005, I get 1 error:
Error 1 error C2027: use of undefined type 'ClassA' d:\v-james\test
code\consoledemo\consoledemo\classb.h 12

So, somebody here please say something about this, thanks.

男儿多薄幸

unread,
Nov 20, 2006, 9:47:19 PM11/20/06
to
ClassA.h should not include the ClassB.h


"Hooyoo 写道:

Hooyoo

unread,
Nov 20, 2006, 10:04:26 PM11/20/06
to
I know in these similar codes ClassA.h no need to include classb.h,
but in my real project I need do this.
Can I solve this problem in other ways?

mimi

unread,
Nov 20, 2006, 10:05:52 PM11/20/06
to

"Hooyoo 写道:

"
> Following are similar codes of my project:
> At first I define two classes in two files:
> //ClassA.h
> #pragma once
> #include "ClassB.h"
>
> class ClassA
> {
> public:
> ClassA(void){};
> public:
> ~ClassA(void){};
> };
>
> //ClassB.h
> #pragma once
> #include "ClassA.h"

Here, you include "ClassA.h" in "ClassB.h", and include "ClassB.h" in
"ClassA.h". I am not quite clear about the link issues.Maybe some one
could explain it more clearly.
But I am sure that there is only one "include" works, and it seems to
be the include "ClassB.h" in "ClassA.h", as you declare "class ClassA"
below.

> class ClassA;

Here, you pre-declare the classA.It just tell the compile that ClassA
is a class defined somewhere, so you can declare instances of ClassA in
this file scope.But ClassB doesn't know anything about ClassA.

> class ClassB
> {
> public:
> ClassB(void){};
> public:
> ~ClassB(void){};
> void DoSomething(ClassA obj){};

When you define the member function Dosometing, you just know ClassA is
a class but nothing more. Access to any member of the classA will be
undefined.When the function takes place, the compile does not know how
to create a temporary object of ClassA, as "it was not defined".
You could use ClassA * here just for compile, but you still can't
access any member of ClassA through the pointer.

cppcoder

unread,
Nov 20, 2006, 10:29:02 PM11/20/06
to

no_dot_h headers like to go with #ifndef-#define-#endif

Peter Liu

unread,
Nov 20, 2006, 10:40:39 PM11/20/06
to
Compiler job do it, because it don't recognise what to compile first
giving some file, by what you say, ".h" files. Also, i think always
writing 'public' to indicate what is publicised is good too. That
increase readable.

Best,
Peter Liu

Ben Howards

unread,
Nov 20, 2006, 11:06:11 PM11/20/06
to
That's not really true, #defien is kewords originally from C not C++.
header files u say are c++ not c. there is no such things as #ifndef
definetion in C++.

-Ben Howards
~FPCP=for potatoes chip pickers~

Alf P. Steinbach

unread,
Nov 20, 2006, 11:18:20 PM11/20/06
to
* Ben Howards:
> [top-posting].

Please don't -- see FAQ item 5.4.

Besides, what you wrote is incorrect.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?

Message has been deleted

gustavo...@gmail.com

unread,
Nov 21, 2006, 7:59:20 AM11/21/06
to
Hooyoo,

You must move what is common for both files to a third one, and then
include this third one to both of your original files.

Howard

unread,
Nov 21, 2006, 11:02:05 AM11/21/06
to

"Hooyoo" <zhao_...@126.com> wrote in message
news:1164078266....@h48g2000cwc.googlegroups.com...

Please don't top-post. Put your replies at the end, or interspersed with
what you're replying to. (I've re-arragned the converstaion below.)

>
>
> "Hooyoo P45@#:


> "
> > Following are similar codes of my project:
> > At first I define two classes in two files:
> > //ClassA.h
> > #pragma once
> > #include "ClassB.h"
> >

Why do you need to include that header?

> > class ClassA
> > {
> > public:
> > ClassA(void){};
> > public:
> > ~ClassA(void){};
> > };
> >
> > //ClassB.h
> > #pragma once
> > #include "ClassA.h"
> >
> > class ClassA;

Why are you forward-declaring ClassA and ALSO including its header? Do one
or the other.

> >
> > class ClassB
> > {
> > public:
> > ClassB(void){};
> > public:
> > ~ClassB(void){};
> > void DoSomething(ClassA obj){};
> > };
> >
> >
> > Then main function:
> > //main.cpp
> > #include "ClassB.h"
> >
> > int main(void)
> > {
> > return 0;
> > }

Why do you include a file but never use it?

> >
> > When I complie these codes in VS2005, I get 1 error:
> > Error 1 error C2027: use of undefined type 'ClassA' d:\v-james\test
> > code\consoledemo\consoledemo\classb.h 12
> >
> > So, somebody here please say something about this, thanks.

DP6y6`1!PR wrote:
> ClassA.h should not include the ClassB.h

> I know in these similar codes ClassA.h no need to include classb.h,


> but in my real project I need do this.

Why? Show us code which actually represents the problem you're having. The
above code does not.

> Can I solve this problem in other ways?

Yes, I'm sure you can, but we don't know what the problem is.

You might want to look at the FAQ: http://www.parashift.com/c++-faq-lite/

Or do a Google Search for "C++ circular dependency".

-Howard


Howard

unread,
Nov 21, 2006, 11:04:03 AM11/21/06
to

"Howard" <ali...@hotmail.com> wrote in message
news:1qF8h.87132$Fi1....@bgtnsc05-news.ops.worldnet.att.net...

>
> "Hooyoo" <zhao_...@126.com> wrote in message
> news:1164078266....@h48g2000cwc.googlegroups.com...
>
> Please don't top-post. Put your replies at the end, or interspersed with
> what you're replying to. (I've re-arragned the converstaion below.)
>

Looks like I re-arranged a few letters there! I think my fingers are
dyslexic. :-)

Should be:
"re-arranged the conversation"

-Howard


Hooyoo

unread,
Nov 21, 2006, 9:21:11 PM11/21/06
to

Thanks to all guys. But I think only mimi really understand me, other
guys totally lost, but still thank you.

Howard

unread,
Nov 27, 2006, 12:58:45 PM11/27/06
to

"Hooyoo" <zhao_...@126.com> wrote in message
news:1164162071.2...@m7g2000cwm.googlegroups.com...

> Thanks to all guys. But I think only mimi really understand me, other
> guys totally lost, but still thank you.

Well, if we were lost, it's because you didn't post "real" code, and didn't
follow up with answers to our questions. Don't blame us if we can't read
your mind.


Tristan Penman

unread,
Nov 28, 2006, 7:42:50 PM11/28/06
to
If I'm not mistaken, you can solve this problem doing the following.
Note that no extra files are included in ClassA.h and ClassB.h


// File: ClassA.h
class ClassB; // Declaration of ClassA so that ClassB knows it exists
class ClassA
{
// something to do with ClassB
};

------------------------------------------------

// File: ClassB.h
class ClassA; // Declaration of ClassB so that ClassA knows it exists
class ClassB
{
// something to do with ClassA
}

------------------------------------------------

// File: ClassA.cpp
#include "ClassA.h"
#include "ClassB.h"

-------------------------------------------------

// File: ClassB.cpp
#include "ClassA.h"
#include "ClassB.h"

The limitation of this is that you can't access members of ClassA in
ClassB.h, or ClassB in ClassA.h. You can, however, use ClassA.cpp and
ClassB.cpp to do anything you need.

I have not tested this with anything more than a few pointers. (i.e
ClassA * pClassA). I'm not sure if it will let you use non-pointer
members to cross-referenced classes.

-- Tristan.

tetra

unread,
Nov 29, 2006, 12:07:01 PM11/29/06
to
Hi!

I think that the only one who realy touched the real problem was
Howard. Hooyoo, you did created a CYCLYC dependency between files!!!
That's the problem! A solution would be to use pointers and references
into one of the headers and to elimnate the need to include the header
itself. In that case the compilator won't ask you about the class
definition. It suffices the declaration. Thus, try to have, let's say
in header of classA, only pointers and references of type classB (every
method of classA that was previously inline and made calls to classB
goes into .cpp):

//ClassA.h
#pragma once
//declare classB
class classB;

class ClassA
{
public:
ClassA(void) : cB ( 0 ){};
const classB & func1( classB *) ;
void funct2(const classB & );

public:
~ClassA(void){};

private:
classB *cB;
};


Now, everything that is releated to the implementation of B goes into
.cpp:

//ClassA.cpp
#include "ClassA.h"
#include "ClassB.h" // HERE YOU CAN INCLUDE classB

const classB & ClassA::func1( classB *){...}
void ClassA::funct2(const classB & ) {...}


The header of B could remain the same:

//ClassB.h
// #pragma once
#include "ClassA.h"

//!!!!!!!!! it doesn't matter if you declare the class after its
definition
class ClassA;

class ClassB
{
public:
ClassB(void){};
public:
~ClassB(void){};
void DoSomething(ClassA obj){};
};

Then main function:
//main.cpp
#include "ClassB.h"

int main(void)
{
return 0;
}

enjoy,
dreqEu.

Salt_Peter

unread,
Nov 29, 2006, 5:39:49 PM11/29/06
to

tetra wrote:
> Hi!
>
> I think that the only one who realy touched the real problem was
> Howard. Hooyoo, you did created a CYCLYC dependency between files!!!
> That's the problem! A solution would be to use pointers and references
> into one of the headers and to elimnate the need to include the header
> itself. In that case the compilator won't ask you about the class
> definition. It suffices the declaration. Thus, try to have, let's say
> in header of classA, only pointers and references of type classB (every
> method of classA that was previously inline and made calls to classB
> goes into .cpp):
>
> //ClassA.h
> #pragma once
> //declare classB
> class classB;

classB does not exist

>
> class ClassA
> {
> public:
> ClassA(void) : cB ( 0 ){};

remove semicolon above.

> const classB & func1( classB *) ;

classB does not exist.

> void funct2(const classB & );
>
> public:
> ~ClassA(void){};
>
> private:
> classB *cB;

classB does not exist.

> };
>
>
> Now, everything that is releated to the implementation of B goes into
> .cpp:
>
> //ClassA.cpp
> #include "ClassA.h"
> #include "ClassB.h" // HERE YOU CAN INCLUDE classB
>
> const classB & ClassA::func1( classB *){...}

same, there is no classB, only ClassB

> void ClassA::funct2(const classB & ) {...}
>
>
> The header of B could remain the same:
>
> //ClassB.h
> // #pragma once
> #include "ClassA.h"
>
> //!!!!!!!!! it doesn't matter if you declare the class after its
> definition
> class ClassA;
>
> class ClassB
> {
> public:
> ClassB(void){};

remove the semicolons

> public:
> ~ClassB(void){};
> void DoSomething(ClassA obj){};

remove the semicolon above

> };
>
>
>
> Then main function:
> //main.cpp
> #include "ClassB.h"
>
> int main(void)
> {
> return 0;
> }
>

The correct way to forward declare would be as follows, note that
templates would do away with the problems at hand:

// ClassA.h
#ifndef CLASSA_H_
#define CLASSA_H_

#include "ClassB.h"
class ClassB;

class ClassA {
ClassB* p_B;
public:
ClassA( void ) : p_B(0) { }
~ClassA() { }
const ClassB& func1() const;
void funct2(const ClassB &);
};
#endif

//ClassA.cpp
#include "ClassA.h"

const ClassB& ClassA::func1() const
{
return *p_B;
}
void ClassA::funct2(const ClassB& r_b)
{
// ...
}

// ClassB.h
#ifndef CLASSB_H_
#define CLASSB_H_

#include "ClassA.h"
class ClassA;

class ClassB {
public:
ClassB() { }
~ClassB() { }
void DoSomething( const ClassA& r_a ) { }
};
#endif

// test.cpp
#include "ClassB.h"

int main()
{
ClassB instance;
return 0;
}

Although i'ld rather *.hpp headers over *.h headers.

0 new messages