用C ++解释空白类函数

时间:2011-08-03 15:21:06

标签: c++ class function declaration

class forums : public master{
public:
    forums() : next(0),prev(0) {}
}
  1. 请解释下一个(0)和上一个(0)的功能究竟是什么意思?

  2. 用逗号(,)分隔功能是什么意思? 这些函数旁边的空括号{}有什么影响?

  3. 我是C ++的初学者,试图找出这意味着什么,或者用于这些写作方式的用途?

  4. 它是否特别适用于覆盖?

5 个答案:

答案 0 :(得分:8)

你所拥有的是“初始化列表”。

代码正在设置类实例的nextprev成员的初始值。

如果nextprev是类的实例,那么该代码可能会调用构造函数,或者如果它们是基本类型,则可能只为它们赋值。

它们以逗号分隔,因为这就是初始化列表的语法。

空括号表示forums构造函数的主体 - 在此示例中构造函数本身没有任何反应,因为工作是在初始化列表中完成的。

答案 1 :(得分:2)

1)它初始化next和prev为0,如初始化,而不是赋值。

2)这就是构造函数初始化列表。没有它,你需要分配下一个&在构造函数体中prev为0。那不是一回事。您需要了解对象初始化和赋值之间的区别。对于某些类型,引用和const对象,初始化列表是必需的。对于复杂的对象,你就要去使用初始化列表因为分配在构造体的对象时,你会支付对象及其分配的初始化更好。对于简单的整数类型,没有差别,但对与类型构造函数,这里,因为典型地,分配几乎与初始化为昂贵的。

这里,正文是空的,因为只有next和prev需要初始化,不需要做任何其他事情。

另外,成员初始化顺序非常严格,它按声明的顺序发生。您在初始化列表中将其写下来的顺序无关紧要,它以声明顺序发生。

非常重要,要了解初始化和分配。

同时理解声明与定义。如果你不理解这些概念,就会出现很多混乱。

3)这是基本的对象构造。有一个空体,因为必须有一个身体;它什么都不做。

答案 2 :(得分:1)

答案 3 :(得分:1)

这不是一个功能。 它具有与以下相同的功能:

forums()
{
    next = 0;
    prev = 0;
}

next和prev可能是您基类的成员。

但是存在差异 - 例如,使用初始化列表比之后为成员分配值更快。

答案 4 :(得分:1)

简短回答

这是一个具有空主体的构造函数,以及一个成员初始化列表,它将两个数据成员初始化为值0

  • class-name([ ctor-args ]) [ : member-init-list ] { [ ctor-body ] }

  • 其中member-init-listmember-name(args) [, member-name(args) [, ... ] ]

(注意:不是实际的C ++词汇语法结构)


答案很长

背景

采用以下类定义:

struct Base {};
struct Derived : Base {};

您可能已经知道Derived来自Base

您可能已经知道DerivedBase都有合成(隐式声明)默认(不带参数)构造函数。 Derived的构造函数隐式/自动调用Base的。

现在让我们添加一个基本的成员函数:

struct Derived : Base {
   void foo() {}
};

我已声明定义了此成员函数foo;它的身体是空的,所以当你调用它时没有任何反应。这是毫无意义的,但它完全有效。

现在,让我们创建自己的构造函数:

struct Derived : Base {
   Derived() {}
};

这看起来更熟悉。它仍然是一个空特殊的[特殊]函数,Base构造函数仍然被隐式调用。我们没有改变它。


处理数据成员

让我们添加一些数据成员并在我们的构造函数中设置它们的值:

struct Derived : Base {
   Derived() {
      x = 0;
      y = 0;
   }

   int x, y;
};

对象构建后,xy都将具有值0。这仍然是C ++的基础。

但您 在初始化它们的可能性之后,你只需要为它们分配

事实上,内置类型的数据成员没有隐式初始化,所以让我们选择一个更好的例子:

struct Derived : Base {
   Derived() /* HERE */ {
      x = "";
      y = "";
   }

   std::string x, y;
};
构造函数体中的代码运行之前,

xy被隐式初始化。当构造函数体开始运行时,将初始化的所有成员已经初始化,并且已经隐式调用了基础构造函数。

我们可以通过在上一个代码段中编写/* HERE */的位置写一个成员初始化列表来拦截此行为并提供我们的自己的初始化值。使用成员初始化列表,代码段如下所示:

struct Derived : Base {
   Derived() : x(""), y("") {
      x = "";
      y = "";
   }

   std::string x, y;
};

哇!好;现在我们将字符串初始化为"",稍后在构造函数体中为它们分配相同的空值。我们可以摆脱那些任务,然后:

struct Derived : Base {
   Derived() : x(""), y("") {}

   std::string x, y;
};

现在构造函数体是空的,但构造函数仍然可以执行操作。它隐式调用基础构造函数,并且显式将数据成员xy初始化为空字符串。

而且,因为std::string有一个默认的构造函数,我们可以写一下:

struct Derived : Base {
   Derived() : x(), y() {}

   std::string x, y;
};

回到原始示例,这同样适用于内置类型的对象。让我们考虑两个方面:

struct Derived : Base {
   Derived() : next(0), prev(0) {}

   Derived* next;
   Derived* prev;
};

处理基类

另外,作为额外的奖励,我们可以使用成员初始化列表来明确调用基础构造函数

struct Derived : Base {
   Derived() : Base(), next(0), prev(0) {}

   Derived* next;
   Derived* prev;
};

除非基础构造函数需要一些参数,否则这是毫无意义的:

struct Base {
   Base(int x) {}
};

struct Derived : Base {
   Derived() : Base(0), next(0), prev(0) {}

   Derived* next;
   Derived* prev;
};

我希望这很有用。