为初学者澄清C++中类定义和实现的一些细节



我是C++的初学者,正试图通过看例子来学习。下面是一个我不完全理解其含义的类的定义示例:

class MyClass{
public:
  std::string name;
  void *data;
  MyClass(const std::string& t_name, void *t_data) : name(t_name), data(t_data) {}
};

以下是我的理解:name和*data是类的变量,MyClass(…)是构造函数。的含义是:左侧类派生自右侧类。然而,这部分代码的含义是什么:

MyClass(const std::string& t_name, void *t_data) : name(t_name), data(t_data) {}

以下是问题:

  1. 什么是"tdata"one_answers"tname"?它们是"数据"one_answers"名称"的初始值吗?这里使用t的原因是什么
  2. 上一行中的意思是什么
  3. 那行末尾的{}是什么

谢谢你的帮助。TJ

什么是"tdata"one_answers"tname"?它们是"数据"one_answers"名称"的初始值吗?

它们是传递给构造函数的参数。如果一个对象被创建为

MyClass thing("Fred", some_pointer);

那么,在构造函数中,t_name具有值"Fred",而t_data具有值some_pointer

这里使用t的原因是什么?

有些人喜欢标记参数,给类成员起不同的名字,但除非你愿意,否则没有必要这样做

上一行中的意思是什么?

这标志着初始化程序列表的开始,该列表初始化类成员变量。以下初始化程序name(t_name), data(t_data)使用构造函数的参数初始化这些成员。

那行末尾的{}是什么?

这是构造函数的主体,就像函数体一样。他们中的任何代码都将在成员初始化后运行。在这种情况下,没有其他事情可做,所以身体是空的。

使用初始化器列表初始化成员是一种很好的C++实践。

  1. t_name、t_data是参数名称
    • "t_"前缀仅用于将其与名称相似的成员字段区分开来
    • 使用类似于函数调用的语法对成员进行初始化,但这是一个正确的初始化/构造,因此您应该这样想
  2. 冒号表示初始值设定项列表的开头
  3. 空大括号{}表示构造函数的主体(在初始化成员之后发生)为空

MyClass(const std::string&t_name,void*t_data):名称(t_name),数据(t_data){}

是类的构造函数,您应该用字符串和void*参数初始化类,然后用传递的参数初始化类字段(名称和数据)。

1) t_data和t_name是进入构造函数的参数。当您创建此类的实例时,您将执行以下操作:

MyClass * myNewClassInstance = new MyClass("My name", &myData);

现在构造函数将"My name"(std::string形式)作为t_name,并将指向myData的指针作为t_data。

2) 这里的冒号不是指派生类这里说的是"初始值设定项列表"。查看Prashant的答案链接,或者对此进行一些挖掘。基本上,这是将成员变量name设置为t_name(这是我们在上例中传递给构造函数的std::字符串),并将data设置为t_data(空指针)。(见下文附加说明)

3) {}是构造函数的实际定义。它是空的——这里没有代码。因此,构造函数所要做的就是初始化成员变量(如初始化器列表所定义的),而不是别的。

现在,让我们以一种更适合初学者的格式查看完全相同的类

// The declaration of MyClass.  This would often show up in a header (.h) file
class MyClass {
public:
  // Member variables
  std::string name;
  void * data;
  // Declaration of constructor -- we haven't defined what actually does here, just
  // what parameters it takes in.
  MyClass(const std::string& t_name, void * t_data);
}
// We declared what the class "looks like" above, but we still have to define what
// the constructor does.  This would usually show up in a .cpp file
// This is the constructor definition.  We have to specify that it's part of the
// The extra "MyClass::" specifies that it's part of the MyClass namespace that we
// declared above.
MyClass::MyClass(const std::string& t_name, void * t_data)
{
  // Set our member variables to what was passed in.
  this.name = t_name;
  this.data = t_data;
}

上面的版本做了完全相同的事情(初始化器列表和构造函数中的传统初始化之间有一些细微的区别,你可能还不关心——如果你好奇的话,请参阅其他关于这方面的参考)。

很明显,这会占用更多的空间,这正是为什么经常使用更压缩的格式。但当你刚开始的时候,这样做会让事情变得更加清楚。当涉及到函数(即构造函数)时,理解声明和定义之间的区别是很重要的,因为您发布的示例在经常分离的情况下同时进行这两种操作。

我是C++的初学者,正在尝试通过看例子来学习。

不管出于什么原因,这在C++中比在Perl、Python、Java甚至C中更难做到。我不推荐这门课程;相反,你可以投资一本好书。

以下是我的理解:

让我们从这个开始。我认为你没有你声称的那么理解。

name和*数据是类的变量

没有。CCD_ 10和CCD_。它们的类型分别为std::stringvoid*

MyClass(…)是构造函数。

是的。

的含义是:左侧类是从右侧类派生而来的。

不,:在不同的语境中意味着不同的东西。在示例中使用它的上下文中,它表示后面有一个初始值设定项列表。

然而,这部分代码的含义是什么:

什么是";t_ data";以及";t_name"?

它们是构造函数中的局部变量。具体来说,它们是传递给函数的参数。

它们是"0"的初始值吗;数据";以及";name";?

这就是它们在这个样本中的使用方式。具体来说,它们被传递给初始化器列表中的dataname初始化器。

这里使用t的原因是什么?

这纯粹是这位作者的惯例。我以前从未见过那种大会。

上一行中的意思是什么?

它引入了一个初始值设定项列表。此构造仅用于构造函数成员函数。每个命名成员都由列出的值初始化。(注意:值不需要来自参数——它们可以是任何合法的表达式,因此:MyClass(int ii) : i(ii), j(cos(0) / 2), k(&global_variable) {}可能是合法的构造函数。)

那行末尾的{}是什么?

构造函数成员函数的主体。由于构造函数的所有工作都是在初始值设定项列表中完成的,因此函数的主体是空的。

最新更新