简体   繁体   English

对 C++ 类的使用感到困惑

[英]Confused about C++ class usage

The following is the code which makes me a little confusing about the usage of class.以下是让我对 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.这里的“FESystem”、“DoFHandler”和“FE_Q”是头文件中的一些预定义类。 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? (1)为什么构造函数“fe”和“dof_handler”在类“FE”本身之外声明,是否有可能在第一个括号内,即在“FE”类定义内声明它们?

(2)What are the meanings of the double colon and colon " :: " and " : " in the code respectively? (2)代码中的双冒号和冒号“ :: ”和“ : ”分别是什么意思? 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++.我是 C++ 新手。 Could anyone give me some help?谁能给我一些帮助? Appreciate it so much!太欣赏了!

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.在本例中,它是 FEM 类的构造函数的实现。 If FEM had a method DoIt(), the implementation might look like:如果 FEM 有一个方法 DoIt(),则实现可能如下所示:

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 .所以在上面的代码中,FEM 的构造函数正在将参数传递给它的成员fe FESystem must have a constructor which takes a FE_Q << dim >>, and an int as parameters. FESystem 必须有一个构造函数,它接受一个 FE_Q << dim >> 和一个 int 作为参数。 It is also passing something to the DoFHandler but it's not clear what triangulation is in the code.它也在向 DoFHandler 传递一些东西,但不清楚代码中的triangulation是什么。 This doesn't look like it would compile.这看起来不会编译。

(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? (1)为什么构造函数“fe”和“dof_handler”在类“FE”本身之外声明,是否有可能在第一个括号内,即在“FE”类定义内声明它们?

Yes, for a templated class, they can be inside or outside the "FE" template class definition.是的,对于模板化类,它们可以位于“FE”模板类定义的内部或外部。 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.但是,对于常规的非模板化类,请将您的类外实现放在相应的源 ( .cpp ) 文件中,而不是在类下方或类中。 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? (2)代码中的双冒号和冒号“::”和“:”分别是什么意思? 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.这使得可以从两个不同的类中命名完全相同的 2 个函数而不会发生名称冲突。 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:并将其放在您的源 ( .cpp ) 文件中:

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.在 Java 或 C# 中,这已被简化为一个点。

The single colon in this particular case is a very special feature of C++ constructors.这种特殊情况下的单冒号是 C++ 构造函数的一个非常特殊的特性。 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:您可能希望在.cpp源文件中像这样编写构造函数:

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.在这个特殊的例子,如果你初始化ba ,优化将无法正常工作。

C++ can be tricky at first to understand, but it is a very powerful language and is really fun to learn. C++ 一开始可能很难理解,但它是一种非常强大的语言,学习起来真的很有趣。

Class methods in C++ are usually defined outside of the class definition. C++ 中的类方法通常在类定义之外定义。 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.这与 Java、Python 等不同。它有一个很好的理由:类的定义只包含其方法的原型,即所谓的声明。 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.方法背后的实际程序可以单独编译,并在链接阶段添加。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM