declaring class inside a header file in C++ [duplicate] - c++

This question already has answers here:
When can I use a forward declaration?
(13 answers)
Closed 5 months ago.
I am trying to understand the src code of FESVR in RISCV, I often come across using of class <class_name> inside a header file like the code linked below
https://github.com/riscv-software-src/riscv-isa-sim/blob/master/fesvr/elfloader.h
I know you can define a whole class inside a header file and include that header file inside a c++ file and use the object directly, but the code above does not completely define the class or create an object it just declares it.
Can anyone explain, what does declaring a class like this achieves?

It's called a forward declaration.
When you're only declaring functions, fields, etc., which use a reference or a pointer to a certain type, you don't necessarily have to know the complete type in order for the compiler to make sense of your code. It just needs to know that the type exists, you did not make any spelling mistakes, etc. E.g. at that point the type can be incomplete and a forward declaration is sufficient. This saves you from having to include the header file which declares the entire type, which saves compile time. Additionally it can break cyclic dependencies.
Only at the place where the type is actually used (in your case most likely in the .cpp file), the compiler must know whether the type actually has the fields or methods you're referring too, it must know the size of the type, etc.. E.g. the type must be complete at that point.
Use forward declarations wherever possible.
See:
C++ class forward declaration
https://en.wikipedia.org/wiki/Forward_declaration

Related

C++ (and ROS) - Include vs. forward declare of reference with set default and typedef

I have two very related questions regarding forward declarations, their advantages and difference with #includes. After reading on them it's still unclear to me if:
using a ConstPtr from a ROS message (like this) counts as a pointer and can be (somehow) forward declared, or requires an #include;
void foo(const Eigen::Vector3d& scale={0.001, 0.001, 0.001}); in a .h file would be fine with something like (but this doesn't actually compile)
namespace Eigen
{
class Vector3d;
}
at the top of the .h after all the other #includes or if I should use the proper header.
To be clear, the second issue is with the fact scale has a default value, which is actually the one I will always be using in the .cpp. This is the only instance where I'm using a Vector3d.
I'm also fairly certain if the forward declaration is enough I therefore would not need to include the proper header in the .cpp as well, since I'm only ever using the default value inside the method.
A forward declaration of X is sufficient to use an X* or X& as a function parameter or class member, because the full definition of a class is not needed to be able to use its address.
But in order to create an object of that class, even one with a default value, you're going to need its definition.

Forward declaration or complete definition required [duplicate]

This question already has answers here:
When can I use a forward declaration?
(13 answers)
In C++, I want two classes to access each other
(1 answer)
Closed 9 years ago.
Although i have been using forward declaration for a considerable amount of time but never gave a thought to it seriously (my mistake)
Would be helpful if someone could give me pointers or any link regarding following queries :
How do we determine if we require a forward declaration or include is required ?
How does compiler actually works in such cases ? any overhead ?
Suppose i have two interdependent classes A and B. Both of them uses objects of each other, do i need to forward declare in both the classes.
I'd say that:
If you only need a reference or a pointer to a class in the header -> use forward declaration.
The overhead with an include is that the compiler will see more dependencies for the current header, and will thus recompile your c++ body file perhaps unneccesarily.
If possible yes.
A forward declaration can always be used, when the compiler only needs to know that some object exists, but doesn't need it's size or other details iof the object.
For example in some .h file you have:
MyClass *foo(MyClass *p);
In example1.cpp:
// No include needed, forward declaration is ok.
MyClass *foo(MyClass *p)
{
foo2(p);
return p;
}
In example2.cpp:
// include needed, forward declaration is not ok.
MyClass *foo(MyClass *p)
{
p->ClassFkt();
return p;
}
In example3.cpp:
// include needed, forward declaration is not ok.
MyClass *foo(MyClass *p)
{
MyClass *n = new MyClass();
foo2(p, n);
return n;
}
Here you have a prototype of a function which takes a pointer. A pointer is always of known size, so a forward declaration can be used here.
As long as you only use the pointer, for example to pass it on, to some other function, you don't need the include. If you try to access some members or do other operation which requires to know more details, you need to include the header file as well. In the above example1 you wouldn't need the full declaration and the forward declaration is sufficient. In the secaond example it is not, because the compiler doesn't know if your class has the function which is invoked. In the third example only pointers are used, but because of the new the size needs to be known, so a forward declaration is not enough.
In order to avoid extra header depencies, you can use the forward declaration in the .h file in the above example, and do the include only in the cpp file itself.

class forward declaration

Can I use forward declaration for a class in order to put it's definition and Implementation later in the program after it's been used (similar to what is done about functions)?
(I need to join multiple source files of a program into a file, and i want to put the classes' definitions and Implementations at the end of the file in order to main be at the top of the file.)
Yes you can, to a certain extent.
You have to realize that the C++ compiler is quite stupid, and doesn't read ahead. This is the reason why you have to use function prototypes (among some other reasons).
Now, a function isn't hard for compiler to resolve. It just looks at the return type of the function, and the types of the parameters of the function, and just assumes that the function is there, without any knowledge about what's actually inside the function, because it ultimately doesn't matter at that point.
However, the contents of the class do matter (the compiler needs to know the size of the class for example). But remember about the not reading ahead bit? When you forward define a class, the compiler doesn't know about what's in it, and therefore is missing a lot of information about it. How much space does is need to reserve for example?
Therefore, you can forward define classes, but you can't use them as value types. The only thing you can do with it (before it has been concretely declared), is use pointers to it (and use it as a function return type and template argument, as pointer out by
#Cheersandhth.-Alf).
If the thing you need to use isn't a pointer, you should probably use headers (read this if you want to learn more about that).
Without a class definition somewhere earlier, you can't use any class members, nor can you create any instances, but you can
use T* and T& types,
use T for formal return type and parameter declarations (yes even by value),
use T as a template parameter,
and possibly more, but the above is what occurred to me immediately.
So if that's all you need, then you're set to go with the forward-declarations.
However, all that the forward declaring buys you in the sketched situation is added work, maintaining the same code in two places, so it's difficult to see the point of it…
Oh, I just remembered, there is a particularly nasty Undefined Behavior associated with forward-declared incomplete types, namely using delete p where p is a pointer to incomplete type. This requires the destructor to be trivial. If the compiler is good then it warns, but don't count on it.
In summary, I would just place main at the very end of that code, where it belongs, avoiding all the problems.

What does "class className;" by itself do in C++? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
C++ - Forward declaration
so in my header file i have a class defined/declared with all it features named User
then in a .cpp source file there is near the top class User;
im new to c, but couldnt find an answer in the few tutorials i looked into so came here
what does it do ?
thankyou.
It's called a forward declaration and enables the compiler to recognise the class without actually knowing its internals. You just inform the compiler that such a class exists, and declaring a pointer to it will not raise an error.
The alternative would be to include the corresponding header file that declares the class, but that would be way too heavy if all you need is having pointers to that type.
It is a so called "Forward declaration": it makes the class known to the compiler, without actually defining it. Note that this is C++, not C.
It declares the class without actually defining it. In that sense, it's no different to:
void doSomething(void);
That prototype tells the compiler that doSomething() exists but doesn't actually specify what it does.
It's generally used where you need the class to exist (so you can reference it somehow) but you don't need to know anything about its properties.

Why other class names are specified above a class? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
When to use forward declaration?
What is the use of specifying other class names above a particular class?
class A;
class B;
class C
{
...
...
};
It's a forward declaration.
As a hangover from C, the C++ compiler works in a top-to-bottom fashion (more or less). If you want your class C to refer to class A or class B in some way (via a pointer or a reference), then the compiler must know about their existence beforehand.
That is called a forward declaration. It allows you to declare a pointer to the type without including its definition. Of course, since the definition doesn't exist at this pointas far as the compiler is concerned, you can only declare pointers or references to the type as the compiler would not know how to construct an object of said type, i.e., it cannot not determine its size.
By forward declaring classes like that, you are telling the compiler that the classes exist, and not to worry, you will link them in later.
This is instead of including the header files with the full definition, and is sufficient if the compiler doesn't need to know what the class looks like. For example if you are only using pointers or references to the class in the current file.
This is called forward declaration and allows the use of those classes in the defined class's prototype.