2

I'm definitely in a desperate case... Using C++, I have defined those two classes:

// Console.hpp
#ifndef CLASS_Console
#define CLASS_Console
#include <iostream>
#include "Window.hpp"

class Console
{
public:
    Window *Win;
    Console(Windows *Win); // Which then does "this->Win = Win;"
    void AppendText(std::string);
    // And some more dozens functions
};
#endif

// Window.hpp
#ifndef CLASS_Window
#define CLASS_Window
#include <iostream>
#include "Size.hpp"

class Window
{
private:
    Console *m_Console;

public:
    Window(); // Which then does "m_Console = new Console(this); m_Console->AppendText("YEAH");"
    Console *getConsole(); // For use by another classes
    Size getSize();
    // And some more Tens and Tens of functions
};
#endif

At first, one will say: "Use forward declaration!"

But given I need to access a number of those dozens of functions (In one way and in the another), is there any way I can avoid using forward declaration?

Thanks for your (future) answers!

ElementW
  • 804
  • 8
  • 23
  • You use include directives in the headers, forward declaration is a way to avoid a circular dependency, which is a promise you will include a definition of that class later (in the cpp file) - you don't run member functions in the header anyway, so you don't need the full definition and can get away with a forward declaration. Forward declaration is the only solution to a problem you eventually get hit by, why would you want to avoid the only solution to a problem? – dtech Sep 05 '12 at 14:12

4 Answers4

5

But given I need to access a number of those dozens of functions (In one way and in the another), is there any way I can avoid using forward declaration?

I am not sure you understand what the forward declaration does. You only need to provide one forward declaration in window.hpp for Console, and then include console.hpp from window.cpp.

David Rodríguez - dribeas
  • 204,818
  • 23
  • 294
  • 489
  • So should I just write "class Window {};" in Console.hpp? Then include Window.hpp in the cpp file, but before or after Console.hpp? – ElementW Sep 05 '12 at 14:05
  • 1
    @gravgun: No, that's not a forward declaration, it's a violation of the One Definition Rule. Leave out the braces. Read http://stackoverflow.com/a/7714388/103167 where I explain the right approach for organizing mutually dependent classes. – Ben Voigt Sep 05 '12 at 14:07
  • @gravgun: A *forward declaration* (technically the term is just *declaration*) just names the type, but provides no definition (curly braces). With your current headers, you can use forward declarations (rather than includes) in both: `class Window;` – David Rodríguez - dribeas Sep 05 '12 at 14:07
  • @BenVoigt Whoops sorry! (I'm just beginning to learn C++ so...) In fact I have already read some forum posts about it, but I always _did_ put the braces (here I can admire how wonderful my stupidity is :P) – ElementW Sep 05 '12 at 14:10
2

No, there's no way to avoid (at least a) forward declaration.

But given I need to access a number of those dozens of functions

Why would this matter? Performance? Have you measured anything yet? If not, you can't talk about performance.

Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
  • Did he mention performance at all, or did you made it up ;) He is obviously new and unfamiliar with the dreaded mechanics of headers, implementations and pre-processor directives that is C++ :) – dtech Sep 05 '12 at 14:18
  • @ddriver I was guessing why he didn't want forward declarations. I didn't know he had no idea what they were. – Luchian Grigore Sep 05 '12 at 14:19
  • I was surprised, because it has... like no relation to performance at all, so just didn't see any logic in involving performance to begin with. No implications on runtime whatsoever. – dtech Sep 05 '12 at 14:21
  • @ddriver there are actually. Without a full definition, you have to separate the implementation in a `cpp` file (can't keep it in the header if you use the object that's forward-declared). That means an extra call because the function can't be inlined. :) – Luchian Grigore Sep 05 '12 at 14:24
  • I have seen plenty of `inline` methods with separate implementations in production grade commercial code. Thou the keyword is just a hint, why would it even be used if inlining demands a full definition? – dtech Sep 05 '12 at 14:28
  • @ddriver depends on numerous things - esp the compiler and if the code is accessible. In different modules, it's nearly impossible. Regardless, this helps with inlining. – Luchian Grigore Sep 05 '12 at 14:33
1

The normal structure is:

  1. declare the first class: class Console;
  2. define the second class: class Window { Console *c; ...};
  3. define the first class: class Console { Window *w; ... };
  4. define the member functions Console::Console() { ... } ...

The first class declaration is enough to let you write the definition of the other class (without the definitions of the member functions).

Then after the definitions of both classes, the member functions are declared, so the code for the member functions can use the members of the other class as needed.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
0

If only one of these class need to be accessed from "outside" by design you could consider nesting Console inside Window (or the other way around)

Laucia
  • 222
  • 2
  • 11
  • Good idea, however I don't like it much... I nest things when they REALLY need to be nested... – ElementW Sep 05 '12 at 14:12
  • It's better not to do it much but has you were looking for alternatives ... The accepted answer is the best though. – Laucia Sep 05 '12 at 14:21