-1

The following is the code which makes me a little confusing about the usage of class.

    template <int dim>
    class FEM
    {
    public:
      FEM (unsigned int order,unsigned int problem); 
      ~FEM(); 
    ...
    FESystem<dim>        fe;
    DoFHandler<dim>      dof_handler;
    ...
    }

    template <int dim>
    FEM<dim>::FEM(unsigned int order,unsigned int problem)
    :
    fe (FE_Q<dim>(order), dim), 
    dof_handler (triangulation)
    {
    ...
    }

Here the "FESystem", "DoFHandler" and "FE_Q" are some predefined class in a header file. I have several questions about this code:

(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?

(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?

    template <int dim>
    FEM<dim>::FEM(unsigned int order,unsigned int problem)
    :
    fe (FE_Q<dim>(order), dim), 
    dof_handler (triangulation){...}

I'm new in C++. Could anyone give me some help? Appreciate it so much!

user123
  • 231
  • 2
  • 12

3 Answers3

0

The double colon is used to specify that you are implementing a function for a specific class. In this case, it's the implementation of the constructor for the FEM class. If FEM had a method DoIt(), the implementation might look like:

template<int dim>
int FEM<dim>::DoIt() { return 1; }

The single colon ":" is used with constructors if you want to pass parameters directly into the constructors of member variables. So in the code above, the constructor for FEM is passing parameters to it's member fe. FESystem must have a constructor which takes a FE_Q << dim >>, and an int as parameters. It is also passing something to the DoFHandler but it's not clear what triangulation is in the code. This doesn't look like it would compile.

bpeikes
  • 3,495
  • 9
  • 42
  • 80
  • Sorry, forget to mention that **triangulation** is also some class defined in a header file. Anyway, thanks for your answer, it seems to make sense for me now! – user123 Nov 11 '15 at 03:11
0

(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.

mchiasson
  • 2,452
  • 25
  • 27
-1

Class methods in C++ are usually defined outside of the class definition. This is different from Java, Python etc. There is a good reason for it: The definition of a class only contains the prototype of its methods, the so called declaration. This is all the information needed for other parts of the program to know how a particular class looks like. Class definitions are saved in header files. And those headers need to be included in every source code that uses the class.

The actual implementation of methods is usually saved in a separate file. Hence the class name and the double colons in front of it to identify the class to which they belong.

The source code in header files will be compiled with every piece of code that uses those class definitions. The actual program behind the methods can be compiled separately, and added during the linking stage.

  • This isn't correct. Especially for templates in C++. Class methods in C++ are often defined inline with the declaration when templates are used. It can also be done when templates are not used as well. The main reason we usually put implementations outside header files is so you don't have to recompile everything that simply needs the header when you make changes to the implementation. – bpeikes Nov 11 '15 at 02:55
  • Thanks for your answer. But what does the single colon mean, I realized that the **fe** and **dof_handler** are instances of some class declared in the **FE** class. – user123 Nov 11 '15 at 02:56
  • Yes, methods can also be defined within the class. However, they will be inline, i.e. the code will be included at every use without actually performing a function call. This is usually done for short getter and setter methods. Still common practice has been to keep methods out of the header files. – drpetermolnar Nov 11 '15 at 03:00
  • Single colon question is addressed here http://stackoverflow.com/questions/1711990/what-is-this-weird-colon-member-syntax-in-the-constructor – drpetermolnar Nov 11 '15 at 03:02
  • 1
    That is also wrong and based on a common misunderstanding of inlining. Inlining in the sense you describe is an optimization the compiler chooses to use at its own discretion when it can. Only the "can" part of that is affected by how you arrange your code. See [this answer](http://stackoverflow.com/a/9734378/1227469) for a full explanation of how inlining works. – JBentley Nov 11 '15 at 03:20
  • Also, it is inaccurate to say that headers containing class definitions need to be used anywhere you use the class. You can keep pointers to a class with just a forward declaration as long as you do not dereference them. – JBentley Nov 11 '15 at 03:31