(1)Why the constructors "fe" and "dof_handler" are declared outside the class "FE" itself, could it be possible that they be declared inside the first bracket, namely inside the "FE" class definition?
Yes, for a templated class, they can be inside or outside the "FE" template class definition. Some people prefer them outside for readability, where they can see the list of every functions available without having to scroll too far down.
However, for regular non-templated class, put your out-of-class implementation in the corresponding source (.cpp
) file instead of below the class or in the class. The reason is, every other classes that will be including your header will be compiling that same implementation over and over, which will slow down your build and make enormous binaries. For templated class, you have no choice. they have to be compiled by each translation units because templated will be code-generated by your compiler.
(2)What are the meanings of the double colon and colon "::" and ":" in the code respectively? Why they are used here? Does the colon ":" mean inheritance?
double colon is your scope. It could be namespace or a class name. This makes it possible to have 2 function named exactly the same from two different classes without name-clashing. It is extremely useful for overriding.
for example, you could have this in a header:
class A
{
public:
virtual foo(int a);
};
class B : public A
{
public:
virtual foo(int a);
};
And have that in your source (.cpp
) file:
A::foo(int a) {
printf("Hello World from A::foo(%s)\n", a);
}
B::foo(int a) {
A::foo(a); // calling the super class's foo(int)
printf("Hello World from B::foo(%s)\n", a);
}
If we had no scope, we wouldn't be able to make the distinction between these two functions. In Java or C#, this has been simplified as a single dot.
The single colon in this particular case is a very special feature of C++ constructors. Only constructors can do this. This is call the 'initializer', and they a neat little optimization that can be used to set default values to your member variables faster than doing it by hand in your construction's function scope.
for example, if you have this class here:
class A
{
public:
A(); // constructor
int a;
float b;
};
You're probably going to want to write your constructor like this in your .cpp
source file:
A::A() {
a = 0;
b = 0.0;
}
But instead, with the initialize, you can write it this way:
A::A() :
a(0),
b(0.0)
{
}
They are supposedly faster to initialize your memory, as long as you initialize them in the same order than the order they are declare in your header. In this particular example, if you initialize b
before a
, the optimization won't work.
C++ can be tricky at first to understand, but it is a very powerful language and is really fun to learn.