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.
Related
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
This question already has answers here:
When can I use a forward declaration?
(13 answers)
Closed 8 years ago.
I was going through a c++ code and saw a header file with below declaration:
file a.h
class xyz;
But that class was not defined any where in the file. I also wrote a code and it perfectly compiles fine. Just wanted to know what is the use of declaring a class like this as it does't enforces programmer to define.
Thanks in advance!!
this is a forward declaration of a class.
you can use xyz* variables in the header file - the linker will resolve the actual class implementation later
That's a forward declaration (or simply declaration) and it allows you to use the name xyz in contexts where a full definition isn't required.
One example is when you have another class which contains a pointer to a xyz:
class xyz;
class Aux
{
xyz* k;
};
Other uses are return types, parameter types and references.
New to C++
there is a namespace i.e. and right after it a couple of class names
namespace abc {
class Cursor;
class BufferAllocator;
....
....
}
What does the above class declaration of Cursor and BufferAllocator do here?
It simply means "these classes exists" in the namespace abc, without providing any informations on their implementations.
It's called forward declarations.
It can be useful for :
Avoiding cycles in header inclusions (When class A has a member of class B, and class B has a member of class A)
Reducing dependencies between classes (because you can have a member pointer to a forward-declared class, but can't have directly a member, as the compiler doesn't know what's the size of the class without its implementation details, but know the size of a pointer). This is used notably in the Pimpl idiom.
(There might be other uses for this, but these are the most obvious that come to mind).
It's a forward declaration. It tells the following code that "there is a class called Cursor. You don't need to know what's in it [because we're only using it as a pointer or reference in the code, until it has been defined]".
Cursor and BufferAllocator are simply being forward-declared in their namespace (so they can be used in pointer/reference contexts).
It's a forward declaration. It can be used to inform the compiler of the existence of types when you're only going to use a pointer or reference to that type. The size of a pointer or reference is invariant of the type that it refers to, so the compiler doesn't need to see the entire definition of the type in that case; it just needs to know that the type exists first.
This can be useful in cases where the header that normally declares the type is large (think headers that include a lot of declarations or template instantiations), in which case it can decrease your compile times (sometimes significantly). You can just forward-declare the type and skip including the header, so your compiler doesn't need to process it.
namespace are helpful in a way they avoid typing particular classname in front of every function.
As you are new you will mostly see using namespace std;
so now you can use cout directly if you do not use this statement then you have to write std::cout for every use of cout
hope this helps
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.
I'm trying to create proper header files which don't include too many other files to keep them clean and to speed up compile time.
I encountered two problems while doing this:
Forward declaration on base classes doesn't work.
class B;
class A : public B
{
// ...
}
Forward declaration on STD classes doesn't work.
namespace std
{
class string;
}
class A
{
string aStringToTest;
}
How do I solve these problems?
The first problem you can't solve.
The second problem is not anything to do with standard library classes. It's because you declare an instance of the class as a member of your own class.
Both problems are due to the requirement that the compiler must be able to find out the total size of a class from its definition.
However, the compiler can work out the size of a pointer to a class, even if it doesn't yet have the full definition of it. So a possible solution in such cases is to have a pointer (or reference) member in the consuming class.
Not much help in the base class case, because you won't get an 'is a' relationship.
Nor is it worth doing for something like std::string. Firstly, it's supposed to be a convenient wrapper around a character buffer, to save you from doing memory management on something so simple. If you then hold a pointer to it, just to avoid including the header, you're probably taking a good idea too far.
Secondly (as pointed out in a comment), std::string is a typedef to std::basic_string<char>. So you need to forward declare (and then use) that instead, by which time things are getting very obscure and hard to read, which is another kind of cost. Is it really worth it?
As answered before by Earwicker, you can not use forward declarations in any of those cases as the compiler needs to know the size of the class.
You can only use a forward declaration in a set of operations:
declaring functions that take the forward declared class as parameters or returns it
declaring member pointers or references to the forward declared class
declaring static variables of the forward declared type in the class definition
You cannot use it to
declare a member attribute of the given type (compiler requires size)
define or create an object of the type or delete it
call any static or member method of the class or access any member or static attribute
(did I forget any?)
Take into account that declaring an auto_ptr is not the same as declaring a raw pointer, since the auto_ptr instantiation will try to delete the pointer when it goes out of scope and deleting requires the complete declaration of the type. If you use an auto_ptr in to hold a forward declared type you will have to provide a destructor (even if empty) and define it after the full class declaration has been seen.
There are also some other subtleties. When you forward declare a class, you are telling the compiler that it will be a class. This means that it cannot be an enum or a typedef into another type. That is the problem you are getting when you try to forward declare std::string, as it is a typedef of a specific instantiation of a template:
typedef basic_string<char> string; // aproximate
To forward declare string you would need to forward declare the basic_string template and then create the typedef. The problem is that the standard does not state the number of parameters that basic_string template takes, it just states that if it takes more than one parameter, there rest of the parameters must have a default type so that the expression above compiles. This means that there is no standard way for forward declaring the template.
If, on the other hand you want to forward declare a non-standard template (non STL, that is) you can do it for as long as you do know the number of parameters:
template <typename T, typename U> class Test; // correct
//template <typename T> class Test; // incorrect even if U has a default type
template <typename T, typename U = int> class Test {
// ...
};
At the end, the advice that was given to you by Roddy: forward declare as much as you can, but assume that some things must be included.
In both cases the compiler needs to know the size of the type. Therefore, a forward declaration will not suffice. A base class could add members or require a virtual table. The string member would require the size of the class to be increase to store the size of the STL string class.
Forward declaring STL classes is often inadvisable since the implementations commonly include explicit template instantiations that speed up compilation.
You're trying too hard to solve something that isn't actually a problem. Use the header files you need, and reduce - WHERE POSSIBLE - the requirement for them. But don't try and take it to extremes because you'll fail.
In some cases, the PIMPL idiom may help you, but not here.
For your base classes, you need to have the full type definition, not just a declaration. Derived type headers will need to #include the header for their base classes.
For classes in the std namespace, you must include the proper header - <string> in this case - and then do one of 3 things:
Fully qualify the type: std::string
aStringToTest
Put a using declaration for just
that type: using std::string;
Put in a using declaration for the
std namespace: using namespace std;
> Seems that forward declaration is useless for base classes and stl classes.
Correction...
Forward declaration is INAPPROPRIATE for base classes and object member. (It's not "useless", it is "inapplicable".)
A base class MUST be declared (not forward declared) when being declared as a based class of another class.
An object member MUST be declared (not forward declared) when being declared by another class, or as parameter, or as a return value. NOTE: by-reference or by-pointer does not have that constraint.
Correction...
Forward declaration of STL classes is -- as per ISO 14882 -- undefined behavior.
http://www.gotw.ca/gotw/034.htm