what does this syntax do?

I have seen code recently that looks something like the following...

#include <this>
#include <that>

class MyClass;

do some other C++ stuff....
.........
.........
public class MyClass
{
}



My question is, what is the purpose of the statement class MyClass right under the include statements? Why is that needed if later down the file you're defining the class anyway?



It's a forward declaration of MyClass.
You typically do this when you define two classes which use one another.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class A;

class B
{
private:

    A *p2a; // uses class A (this wouldn't work without forward declaring class A)
};

class A
{
private:

    B *p2b; // uses class B (works fine because class B is declared before it)
};


By the way, your code is not valid C++ code.
C++ isn't Java, so public is misplaced and you must finish the class body with semicolon ;.

1
2
3
public class MyClass
{
}; // semicolon 

Actually , while compiling any line of code Compiler required his prototype first.

In above example class B using object class A, So Compiler must aware about existence of class A.
To do this we have to give forward declaration of class A above the class B.
Catfish.. So even if both class definitions are in the same header file? And the class I developed? That was just from memory, guess my C# mindset kicked in.
Catfish.. So even if both class definitions are in the same header file? And the class I developed? That was just from memory, guess my C# mindset kicked in.

Do you know what happens whenever you #include a header file?
The header file is copied in the current file, as-is. Try it.

part.txt (save this file in the same folder as test.cpp)
#include <iostream>

int main()
{


test.cpp (compile this file)
1
2
3
4
#include "part.txt"

    std::cout << "Hello, C/C++ World!" << std::endl;
}


Do not confuse header files from C++ with modules from other languages.

In C++ (just like in C), everything must be declared before you use it, and for this purpose it's usually declared in header files. So by including the header files you have the declarations that you need.

There is no concept of module in C and C++. The compiler doesn't bother inspecting the contents of your source files to see if you defined class A later on. If there's no class A (forward-)declaration before class A is used for the first time, the compiler stops with an error.
If you have the complete class definition before you're attempting to use the class name, then no, you don't also need to forward declare.

The point of Catfish's example is that, if the definition of A uses B, and the definition of B uses A, then you can't possibly have this be true. You can't have both of them before each other! So you use forward declaration for one of them.

Note that forward declaration only works for situations where you don't need to know anything about the class - just that it is a class. Usually, this means situations where you want to declare a reference or pointer to the class, but don't need to access any members of it. So:

1
2
3
4
5
6
7
8
9
10
11
12
13
class A;  // Forward declatation

A* objPtr = 0;  // This is OK, it's just a pointer

objPtr->method();  // This is not - you need the class definition for the method declaration

A object;  // This is not - it creates an object, so needs the actual definition

A* Function1(A* obj1, A& obj2);  // This is OK - only pointers and references

A Function2();
void Function3(A obj3);  // These are not, because they use actual objects, so need the definition.
Last edited on
> There is no concept of module in C and C++.

The very existence of the separate compilation model is impossible without the concept of modularity. Modules have been central to software design since 1972, the year David Lorge Parnas published his seminal paper 'On the Criteria To Be Used in Decomposing Systems into Modules'. Ideas which later became enshrined as "high cohesion within modules and loose coupling between modules".


1
2
> A Function2();
> void Function3(A obj3);  // These are not, because they use actual objects, so need the definition. 


Declarations of functions do not use actual objects; they just use the type in name. Those are fine, too.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <memory>

struct A ;

A Function2(); // fine; though A is an incomplete type here, it used only 'in name'

void Function3 ( A obj3 ) ; // also fine; use 'in name'

struct B
{
    A mem_fun( A arg ) const ; // also fine; use 'in name'

    static A sa ; // also fine; use 'in name'

    std::unique_ptr<A> p ; // also fine; std::unique_ptr<> is lazily evaluated

    // int i = sizeof(A) ; // **** error: A is an incomplete type
};

struct A { /* .... */ }; // definition of A, now A becomes a complete type

A Function2() { return A() ; } // fine; A has been defined 

http://coliru.stacked-crooked.com/a/709a024d3eb6fbb9
Declarations of functions do not use actual objects; they just use the type in name. Those are fine, too.


I'm sure I remember seeing compilers complain about trying to do this with only a forward declaration in the past, but I guess I must be misremembering. Thanks for the correction.
The difference is that you cannot actually call Function3 until A is a complete type. (How would you get an instance of A to call it with? How would you know how to copy it?)
Last edited on
Topic archived. No new replies allowed.