2011-09-10 42 views
2

构造函数通过灰尘构建对象。内置数据类型与C++中用户定义的数据类型

这是我近来多次遇到的一个声明。

在初始化内置数据类型变量时,变量也必须“由灰尘构建”。那么,是否还有内置类型的构造函数?

此外,编译器如何以不同的方式处理BUILT IN DATATYPE和USER DEFINED CLASS,同时为每个实例创建实例? 我的意思是关于构造函数,析构函数等的详细信息。

这个关于堆栈溢出的查询是相同的,它有一些相当有趣的细节,最引人注目的是Bjarne所说的......。

Do built-in types have default constructors?

+0

通过内建,你的意思是“原始”类型,如“int”,“char”,数组和指针,还是包含标准库类? – delnan

+0

原始数据类型:) – jsp99

+0

请注意,'std'命名空间中的* all *类也是用户定义的类型。这包括'std :: string','std :: map','std :: vector'等等。 – dalle

回答

1

在初始化内置数据类型的变量,该变量也有从尘土中的“建“。那么,是否还有内置类型的构造函数?

根据要求,我正在从灰尘重建我的答案。

我不是特别喜欢那个“构造函数从尘埃构建物体”的短语。这有点误导。

一个对象,无论是原始类型,指针还是大类的实例,都占用一定的内存量已知的。这种记忆必须以某种方式留在物体上。在某些情况下,该预留存储器被初始化。初始化是构造函数的作用。它们不会留出(或分配)存储对象所需的内存。该步骤在调用构造函数之前执行。

有些时候变量不需要被初始化。例如,

int some_function (int some argument) { 
    int index; 
    ... 
} 

请注意index未被赋值。在进入some_function时,将为变量index预留一大块内存。这个内存已经存在某处;它只是搁置或分配。由于内存已经存在,每个位都会有一些预先存在的值。如果一个变量没有被初始化,它将会有一个初始值。变量index的初始值可能是42或1404197501,或者完全不同的东西。

某些语言提供了一个默认的初始化,以防程序员没有指定一个。 (C和C++不这样做。)有时没有将变量初始化为已知值没有问题。例如,下一个声明可能是一个赋值语句。提供默认初始化的好处在于未能初始化变量是典型的编程错误。缺点是这种初始化有成本,尽管通常很小。当它出现在时间关键的多重嵌套循环中时,这种微小的成本可能会非常显着。不提供默认的初始值符合C和C++的理念,不提供程序员没有要求的东西。

一些变量,甚至非类变量,绝对需要赋予一个初始值。例如,除了在声明语句中,没有办法将值赋给一个引用类型的变量。对于声明为常量的变量也是如此。

某些类具有绝对需要初始化的隐藏数据。某些类有const或绝对需要初始化的引用数据成员。这些类需要被初始化或构建。并非所有的类都需要初始化。没有任何虚函数的类或结构,没有显式提供的构造函数或析构函数,其成员数据都是原始数据类型,称为普通旧数据或POD。 POD类不需要构建。

底线:

  • 一个目的,无论是原始类型或一个非常复杂的类的一个实例,不“从灰尘内置”。毕竟,尘埃对计算机非常有害。它们是由比特构建的。
  • 为某个对象留出或分配内存并初始化该备用内存是两回事。
  • 需要存储对象的内存被分配,而不是创建。内存已经存在。由于该内存已经存在,构成该对象的位将具有一些预先存在的值。你当然不应该依赖那些先前存在的价值观,但他们在那里。
  • 初始化变量或数据成员的原因是给它们一个可靠的已知值。有时候,初始化只是浪费CPU时间。如果你没有要求编译器提供这样的值,C和C++就认为这个省略是故意的。
  • 某些对象的构造函数不分配存储对象本身所需的内存。在构造函数被调用的时候,这一步已经完成了。构造函数的功能是初始化已分配的内存。

初始响应:

基本类型的变量没有被“从灰尘内置”。存储变量的内存需要分配,但变量可以保持未初始化。构造函数不会从灰尘构建对象。构造函数不分配存储待构造对象所需的内存。该内存在构造函数被调用时已被分配。 (构造函数可能会将某些指针数据成员初始化为构造函数分配的内存,但该指针占用的位必须已经存在。)

某些对象,如基元类型和POD类不一定需要初始化。声明一个没有初始值的非静态基元类型变量,该变量将被初始化。 POD课程也是一样。假设你知道你要在变量的值被访问之前给某个变量赋值。你需要提供初始值吗?编号

有些语言确实给每个变量赋予初始值。 C和C++不这样做。如果你没有要求初始值,C和C++不会强制变量的初始值。初始化的成本通常很小,但它存在。

+0

@大卫..你明白了我的观点..!但我真的无法得到它,你想传达什么。 !你能否以更简单的方式呈现它,删除一些术语? :)谢谢:) – jsp99

+1

@Appy:我已经重建灰尘我的答案。 –

+0

@ DAvid ...我不能指望比这更好的答案...谢谢你:) :) :) – jsp99

5

简单地说,根据C++标准:

12.1的构造[class.ctor]

2.一个构造用于初始化的对象其类型...

所以没有,内置的数据类型(假设你正在谈论像int s和float s这样的东西)没有构造函数,因为它们不是类类型。类类型被指定为这样:

9类[类]

1.类是一类。其名称在 的范围内变成类别(9.1)。

 
     class-name: 
       identifier 
       template-id 

类符阐述型说明符(7.1.5.3)用于 使类名。类的对象由成员和基类对象(可能为 空)序列组成。

 
     class-specifier: 
       class-head { member-specification (opt) } 

     class-head: 
       class-key identifieropt base-clauseopt 
       class-key nested-name-specifier identifier base-clauseopt 
       class-key nested-name-specifieropt template-id base-clauseopt 

     class-key: 
       class 
       struct 
       union 

而且,由于内置的​​类型不一样,声明,他们不能类类型。

那么如何创建内置类型的实例?将内置和类实例存在的一般过程称为初始化,C++标准(8.5)中有一个巨大的8页部分,详细描述了它的详细信息。 Here's some of the rules你可以在8.5节找到。

+0

谢谢:)。你的回答恰到好处。但我需要更多信息。我在哪里可以得到它?这是什么C++标准8.5? – jsp99

+0

@Appy:您可以搜索C++标准14882,并找到工作草案的PDF文件,例如。请注意,有三个版本:1998年,2003年和2011年。我引用的标准是2003版,但2011版应该没问题。 –

0

内置数据类型(基本类型,数组,引用,指针和枚举)没有构造函数。

构造函数是一个成员函数。成员函数只能为一个类类型

C++ 03 9.3/1来定义:在一个类的定义中声明

“功能,但不包括那些与朋友限定声明,被称为该班级的成员职能“。


许多特定语法的(如下所示)的POD类型的次使用可能会给出一个印象是,他们使用的构造函数和拷贝构造函数构建的,但它只是初始化没有任何两个。

int x(5); 
+0

但是构造函数也是一个'东西'(我猜是函数),当我们忘记在类定义中编写它时,或者当我们编写一个空的类定义时,编译器通过DEFAULT引入它。所以,除了会员功能之外,还有更多。 nt它? – jsp99

+1

@Appy:这是一个普通的成员函数。只有特别的事情是,如果你自己没有指定一个,编译器会为你生成一个(如果需要的话)。 –

+0

谢谢.. :)直到现在我有一个印象,一个构造函数是'Divine':p ..很好的知道,它只是一个普通的成员函数! – jsp99

2

如前所述,内置数据类型没有构造函数。

但是,您仍然可以使用类似构造的初始化语法,如int i(3)int i = int()。据我知道,被介绍给语言以更好地支持泛型编程,即能写

template <class T> 
T f() { T t = T(); } 

f(42); 
+0

它与T *的ptr =新T(更多的乐趣)或只是简单的双* PTR =新的双(); –