class names after namespace in C++ - c++

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

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 declaring and using in one step

As an optimisation, or to avoid include looping, a type may be forward declared, This leads to code like:
class A;
class B
{
A *a;
};
If the number of forward declaration becomes large, it can take up a lot of space at the top of the header file. Is there a way of forward declaring and using at the same time? Sort of like:
class B
{
extern A *a;
};
I've never really thought about this before, but I have a header with a bunch of forward declarations and I would like to make it tidier (without farming them off to another include file).
EDIT: I changed 'a' to a pointer, as it was rightly pointed out that you can only use forward declare on pointers and references.
What you're asking isn't completely clear but, if I understand you right, you can forward declare at the same time as declaring your variables:
class B
{
class A* a; // declaring A as class is an in-place forward declaration
};
Is that what you mean?
A forward declaration wouldn't allow you to do
class A;
class B
{
A a;
};
unless A is a reference or pointer type, since a forward declaration doesn't give any additional information on the size of the object (unless for enum class in C++11). So are you using pointers/references? Otherwise it means you are including the definition of A for sure.
Regarding your problem there is no way to forward declare and use a type since we're talking about two different things. A variable declaration doesn't define a type, it defines a variable.
A simple solution to your problem would be to gather all forward declaration in a single header file and include it in the project (or in your eventual precompiled header). This wouldn't create too much problems, since forward declarations don't expose anything nor they are heavyweight.
No, you can't do what you want. This answer about forward declarations should give you all the gory details, but in summary you need the full definition of a type if you want to use it (as including more or less does); not just the fact that it exists (as forward declaring more or less does).

Why are access declarations deprecated? What does this mean for SRO and using declarations?

I've been looking high and low for an answer to what I thought was a fairly simple question: Why are access declarations deprecated?
class A
{
public:
int testInt;
}
class B: public A
{
private:
A::testInt;
}
I understand that it can be fixed by simply plopping "using" in front of A::testInt,
but without some sort of understanding as to why I must do so, that feels like a cheap fix.
Worse yet, it muddies my understanding of using declarations/directives, and the scope resolution operator. If I must use a using declaration here, why am I able to use the SRO and only the SRO elsewhere? A trivial example is std::cout. Why not use using std::cout? I used to think that using and the SRO were more or less interchangeable (give or take some handy functionality provided with the "using" keyword, of which I am aware, at least in the case of namespaces).
I've seen the following in the standard:
The access of a member of a base class can be changed in the derived class by mentioning >its qualified-id in the derived class declaration. Such mention is called an access >declaration. The effect of an access declaration qualified-id; is defined to be equivalent >to the declaration using qualified-id; [Footnote: Access declarations are deprecated; member >using-declarations (7.3.3) provide a better means of doing the same things. In earlier >versions of the C++ language, access declarations were more limited; they were generalized >and made equivalent to using-declarations - end footnote]
However, that really does nothing other than confirm what I already know. If you really boiled it down, I am sure my problem stems from the fact that I think using and the SRO are interchangeable, but I haven't seen anything that would suggest otherwise.
Thanks in advance!
If I must use a using declaration here, why am I able to use the SRO and only the SRO elsewhere?
Huh? You are not able to. Not to re-declare a name in a different scope (which is what an access declaration does).
A trivial example is std::cout. Why not use using std::cout?
Because they're not the same thing, not even close.
One refers to a name, the other re-declares a name.
I am sure my problem stems from the fact that I think using and the SRO are interchangeable
I agree that's your problem, because you are entirely wrong. Following a using declaration it is not necessary to qualify the name, but that doesn't make them interchangeable.
std::cout is an expression, it refers to the variable so you can write to it, pass it as a function argument, take its address etc.
using std::cout; is a declaration. It makes the name cout available in the current scope, as an alias for the name std::cout.
std::cout << "This is an expression involving std::cout\n";
using std::cout; // re-declaration of `cout` in current scope
If you're suggesting that for consistency you should do this to write to cout:
using std::cout << "This is madness.\n";
then, erm, that's madness.
In a class, when you want to re-declare a member with a different access you are re-declaring it, so you want a declaration. You aren't trying to refer to the object to write to involve it in some expression, which (if it was allowed at class scope) would look like this:
class B: public A
{
private:
A::testInt + 1;
};
For consistency with the rest of the language, re-declaring a name from a base class is done with a using-declaration, because that's a declaration, it's not done with something that looks like an expression.
class B: public A
{
private:
A::testInt; // looks like an expression involving A::testInt, but isn't
using A::testInt; // re-declaration of `testInt` in current scope
};
Compare this to the std::cout example above and you'll see that requiring using is entirely consistent, and removing access declarations from C++ makes the language more consistent.

Why doesn't C++ need forward declarations for class members?

I was under the impression that everything in C++ must be declared before being used.
In fact, I remember reading that this is the reason why the use of auto in return types is not valid C++0x without something like decltype: the compiler must know the declared type before evaluating the function body.
Imagine my surprise when I noticed (after a long time) that the following code is in fact perfectly legal:
[Edit: Changed example.]
class Foo
{
Foo(int x = y);
static const int y = 5;
};
So now I don't understand:
Why doesn't the compiler require a forward declaration inside classes, when it requires them in other places?
The standard says (section 3.3.7):
The potential scope of a name declared in a class consists not only of the declarative region following the name’s point of declaration, but also of all function bodies, brace-or-equal-initializers of non-static data members, and default arguments in that class (including such things in nested classes).
This is probably accomplished by delaying processing bodies of inline member functions until after parsing the entire class definition.
Function definitions within the class body are treated as if they were actually defined after the class has been defined. So your code is equivalent to:
class Foo
{
Foo();
int x, *p;
};
inline Foo::Foo() { p = &x; }
Actually, I think you need to reverse the question to understand it.
Why does C++ require forward declaration ?
Because of the way C++ works (include files, not modules), it would otherwise need to wait for the whole Translation Unit before being able to assess, for sure, what the functions are. There are several downsides here:
compilation time would take yet another hit
it would be nigh impossible to provide any guarantee for code in headers, since any introduction of a later function could invalidate it all
Why is a class different ?
A class is by definition contained. It's a small unit (or should be...). Therefore:
there is little compilation time issue, you can wait until the class end to start analyzing
there is no risk of dependency hell, since all dependencies are clearly identified and isolated
Therefore we can eschew this annoying forward-declaration rule for classes.
Just guessing: the compiler saves the body of the function and doesn't actually process it until the class declaration is complete.
unlike a namespace, a class' scope cannot be reopened. it is bound.
imagine implementing a class in a header if everything needed to be declared in advance. i presume that since it is bound, it was more logical to write the language as it is, rather than requiring the user to write forwards in the class (or requiring definitions separate from declarations).

Forward Declaration of a Base Class

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