4

It is possible to declare a class without defining it (forward declaration) as long as it is defined later on within the translation unit. In the case of functions, one can declare a function without defining it within the translation unit, and the linker will link it to its definition in a different translation unit. Is it possible to do the same with class declarations?

(if this is not possible, is there any use to a forwardly declared class without a definition in the current TL, or is that always an error?)

something like this, except this doesn't compile:

mymain.cpp:

class myclass; // declare without defining

myclass::myclass();
void myclass::barf();

int main() {
  myclass *m = new myclass();
  m->barf();
  return 0;
}

myclass.cpp:

#include <iostream>

class myclass { // define the implementation
public:
    myclass();
    void barf();
};

myclass::myclass() { } //empty constructor
void myclass::barf() {
    std::cout << "barfing\n";
}
JanKanis
  • 6,346
  • 5
  • 38
  • 42

3 Answers3

10

It is possible to forward-declare a class, but only pointers and references to forward-declared classes can be used. You can't use an actual object of a forward-declared class because the compiler doesn't know enough about it; in particular it doesn't know how large the object is or what its members are. Trying to forward-declare member functions (as you have done) won't work because the syntax of the forward declaration doesn't allow you to specify whether the functions are virtual or non-virtual (or perhaps inherited from some base class).

It is not often useful to forward-declare a class in a source file, but it can be useful in a header file. In particular it's common to forward-declare a class in a library's public header file and use pointers to that type as opaque handles. The class definition remains private to the library but user code can pass around pointers to objects of that class without ever knowing what the class's implementation looks like. This works particularly well when the pointers are smart pointers.

dajames
  • 2,776
  • 1
  • 20
  • 17
3

You can, but only if you use exclusively pointers or references to that class. But you can't use code referring to that class' members (variables or methods). You can only use it to declare pointer variables to that class.

I would suggest you create a myclass.h header file with myclass' full declaration, and include that header in mymain.cpp.

Pablo Santa Cruz
  • 176,835
  • 32
  • 241
  • 292
  • 1
    Uh? Nope. If `myclass` is not defined, you cannot use `myclass::barf`, not even on a pointer or reference... – peoro Nov 16 '10 at 13:47
  • With a forward declaration of `myclass` you can also declare (but not define or call) functions that take or return `myclass` by value. – Steve Jessop Nov 16 '10 at 15:11
0

You can only do that through hacks.

The declare before use rule doesn't hold within a class (see here).

Otherwise you can do that by declaring your function as a template function, whose template parameter is of myclass (in your example).

The only non-hack way is to define the class (ie. by including the header file its defined in).

Community
  • 1
  • 1
peoro
  • 25,562
  • 20
  • 98
  • 150
  • Why is using templates to solve this kind of a problem a hack? – Moo-Juice Nov 16 '10 at 14:13
  • Because you don't actually need a template function. And if you don't need it, it's better to avoid IMO: templates add many disadvantages, most of them due to compilers (many compilers don't support many features about templates, and their output gets a lot more complex...) – peoro Nov 16 '10 at 14:27