LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 05-28-2011, 02:47 PM   #1
MTK358
LQ 5k Club
 
Registered: Sep 2009
Posts: 6,443
Blog Entries: 3

Rep: Reputation: 723Reputation: 723Reputation: 723Reputation: 723Reputation: 723Reputation: 723Reputation: 723
C++ interdependant classes


I have two C++ classes that depend on each other. Here's a simple example:

Code:
class A
{
public:
	B foo() {}
};

class B
{
public:
	A bar() {}
};

int main()
{
	return 0;
}
It fails to compile:

Code:
$ g++ test.cpp 
test.cpp:4:2: error: ‘B’ does not name a type
Is it possible to make this work?
 
Old 05-28-2011, 02:49 PM   #2
paulsm4
LQ Guru
 
Registered: Mar 2004
Distribution: SusE 8.2
Posts: 5,863
Blog Entries: 1

Rep: Reputation: Disabled
Sure:
Code:
class B;

class A
{
public:
	B foo() {}
};

class B
{
public:
	A bar() {}
};

int main()
{
	return 0;
}
 
1 members found this post helpful.
Old 05-28-2011, 03:43 PM   #3
johnsfine
LQ Guru
 
Registered: Dec 2007
Distribution: Centos
Posts: 5,286

Rep: Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197
I guess there could be cases simple enough that works (just predeclaring B).

Quote:
Originally Posted by paulsm4 View Post
Code:
class B;

class A
{
public:
    B foo() {}
};

class B
{
public:
    A bar() {}
};

int main()
{
    return 0;
}
But in most real world examples, you need to go a step further:

Code:
class B;

class A
{
public:
    B foo();
};

class B
{
public:
    A bar() {}
};

B A::foo() {}

int main()
{
    return 0;
}
In addition to predeclaring B before defining A, I also only declared (not defined) foo inside the definition of A. Then I defined A::foo after defining B.

(In all these examples, I am assuming the {} stands for actual code rather than literally {})

You (MTK358) need to understand the relationship between declaring and defining:

The code in the first post declares and defines A together as one step, similarly for foo, B and bar. But each of those could have declare split from define if you choose.

You cannot avoid declaring A::foo() within defining A, and you cannot avoid declaring B::bar() within defining B.

The way the code looks, it is very clear:
1) Declaring B must precede declaring foo.
2) Declaring A must precede declaring bar.
It seems pretty clear (despite paulsm4's example):
3) Defining B must precede defining foo.
4) Defining A must precede defining bar.

My example sorts all that out by the following sequence:
Declaring B
Defining A including declaring foo
Defining B including declaring and defining bar
Defining foo.

It may be better style (though not needed in this example) to also split defining bar from declaring bar.

Last edited by johnsfine; 05-28-2011 at 03:57 PM.
 
Old 05-28-2011, 10:40 PM   #4
paulsm4
LQ Guru
 
Registered: Mar 2004
Distribution: SusE 8.2
Posts: 5,863
Blog Entries: 1

Rep: Reputation: Disabled
Hi, Mtk358 -

Glad you're squared away. Let me elaborate a bit on what johnsfine was trying to say:

1. You should always strive to separate your interface from your implementation (one of the few things I dislike about Java and C# is they tend to make it harder to do this).

2. If you did this, your interface would go in a .h header, your implementation in one or more .cpp modules ... and the syntax I gave you should work perfectly.

3. Otherwise, you might have problems trying to access any members of the class you forward referenced.

Here's an alternate example:
Code:
// myheader.h
#ifndef MYHEADER_H
#define MYHEADER_H

class B;

class A
{
public:
  A ();
  void someMethod ();
  void someOtherMethod ();
...
  B foo;
};

class B
{
public:
  B ();
  ...
  A bar;
};
#endif
/* MYHEADER_H */
Code:
// mymodule.cpp
#include "myheader.h"

A::A ()
  : foo()
{
  ...
    B foo() {}
};

B::B ()
  : bar()
{
public:
    A bar() {}
};

int main()
{
  ...
}
 
Old 05-29-2011, 08:29 AM   #5
MTK358
LQ 5k Club
 
Registered: Sep 2009
Posts: 6,443

Original Poster
Blog Entries: 3

Rep: Reputation: 723Reputation: 723Reputation: 723Reputation: 723Reputation: 723Reputation: 723Reputation: 723
I do separate the interface and implementation. I didn't in the example becasue it's simpler and still causes the same error.
 
Old 05-29-2011, 01:06 PM   #6
Sergei Steshenko
Senior Member
 
Registered: May 2005
Posts: 4,481

Rep: Reputation: 454Reputation: 454Reputation: 454Reputation: 454Reputation: 454
http://stackoverflow.com/questions/3...ursive-classes - pay attention to pointers to classes.
 
Old 05-29-2011, 01:28 PM   #7
paulsm4
LQ Guru
 
Registered: Mar 2004
Distribution: SusE 8.2
Posts: 5,863
Blog Entries: 1

Rep: Reputation: Disabled
MTK358 -
Quote:
I do separate the interface and implementation.
Sorry - I didn't mean to imply that you wouldn't ordinarily do that. I just wanted to make sure you were crystal-clear with all the responses to your original question (including mine).

Again - glad you're squared away

Sincerely .. PSM
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
C++ classes help allomeen Programming 4 12-26-2005 04:47 PM
Classes in VC++ Diederick Programming 2 11-30-2005 10:57 AM
Possible uses for classes. RHLinuxGUY Programming 4 11-21-2005 10:10 PM
classes in C++ niteshadw Programming 2 07-05-2005 07:05 PM
OOP (PHP) classes and extended classes ldp Programming 3 03-05-2005 11:45 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 09:25 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration