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

时间:2012-07-12 17:49:13

标签: c++ class constructor derived-class

我是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. 什么是“t_data”和“t_name”?它们是“数据”和“名称”的初始值吗?这里使用t_的原因是什么?
  2. 在上面一行是什么意思?
  3. 该行尾的{}是什么?
  4. 感谢您的帮助。 TJ

5 个答案:

答案 0 :(得分:5)

  

什么是“t_data”和“t_name”?它们是“数据”和“名称”的初始值吗?

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

MyClass thing("Fred", some_pointer);

然后,在构造函数中,t_name的值为"Fred"t_data的值为some_pointer

  

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

有些人喜欢标记参数,为类成员提供不同的名称,但除非您愿意,否则无需这样做。

  

在上面这行是什么意思?

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

  

该行末尾的{}是什么?

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

答案 1 :(得分:4)

使用initializer lists to initialize members是很好的C ++实践。

  1. t_name,t_data是参数名称
    • “t_”前缀仅用于将其与类似命名的成员字段区分开来。
    • 使用类似函数调用的语法初始化成员,但这是一个正确的初始化/构造,所以你应该这样想。
  2. 冒号表示初始化列表的开头
  3. 空括号{}指定构造函数的主体(在成员初始化后发生)为空。

答案 2 :(得分:2)

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

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

答案 3 :(得分:0)

对于初学者来说,这是一个有点压缩的例子,但你提出了很好的问题。

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 :: string),datat_data (void指针)。 (参见下面的附加说明)

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;
}

上面的版本做了完全相同的事情(初始化程序列表和构造函数中的传统初始化之间存在一些细微差别,您可能还不关心 - 再次,如果您感到好奇,请参阅有关此内容的其他参考资料)。

很明显,这会占用更多空间,而这正是经常使用压缩格式更多的原因。但是当你刚开始的时候,通过这种方式让事情变得更加清晰。在涉及函数(即构造函数)时,理解声明和定义之间的区别非常重要,因为您发布的示例在它们经常分离的同时进行。

答案 4 :(得分:0)

  

我是C ++的初学者,我试图通过查看示例来学习它。

无论出于何种原因,这在C ++中比在Perl,Python,Java甚至C中更难做。我不推荐这门课程;相反,您可以投资good book

  

以下是我的理解:

让我们从那开始吧。我认为你不像你声称的那样理解。

  

name和* data是类

的变量

没有。 namedata是该类的变量。它们的类型分别为std::stringvoid*

  

MyClass(...)是构造函数。

  

意思是:左侧类来自右侧类。

不,:在不同的环境中意味着不同的东西。在样本中使用它的上下文中,它表示后面有一个初始化列表。

  

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

     

什么是“t_data”和“t_name”?

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

  

它们是“数据”和“名称”的初始值吗?

这就是他们在这个样本中使用它们的方式。具体来说,它们将被传递到初始化列表中的dataname初始值设定项。

  

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

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

  

在上面这行是什么意思?

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

  

该行末尾的{}是什么?

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