2011-07-04 49 views
12

这是关于在C++中使用构造函数的非常简单的问题。我将以采访对话的形式呈现(很难以任何其他形式呈现)在C++中使用构造函数

采访者 -什么是构造函数?
me -构造函数是特殊函数,它确保所有对象在使用前都被初始化。

访问者 -什么是初始值列表?
me -这是一个所有初始化发生的列表。只有在初始化所有数据成员之后才输入构造函数的主体,或者调用所有成员对象的某个构造函数。

面试官 -这意味着初始化是在初始化器列表中执行的,而不是在构造器内部执行的。但你说构造函数初始化对象!你不是吗?你想回答我的第一个问题吗?
me -我认为构造函数不会赋值,它会在已经初始化的成员对象上调用赋值运算符。

所以我想问你可以

初始化列表是如何工作的

函数的起始地址是什么之间&起始括号[{]?

或只是回答我如何说服我的面试官。

+3

“什么是初始化列表?”一个用词不当。你在谈论'ctor-initializer'。初始化器列表完全是其他东西。 –

+1

@Amar - 'int a [] = {1,2,3,4,5};' - '{1,2,3,4,5}'是初始化列表。 – Mahesh

+0

我的意思是构造函数初始化列表; like sample :: sample:A(a)() – Amar

回答

3

你超越了它,允许面试官混淆你。

初始化对象的成员是不是与初始化对象本身一样。仅仅因为成员具有理智的价值观并不意味着这个对象已经被构建。在构造函数完成之前,对象本身尚未正确初始化。

+0

接受这个答案的理由是,你的回答“仅仅因为成员具有理智的价值观并不意味着对象已经被构建”提醒我,只有在完成以下事情之后才能构建对象 - 1)默认ctot &CCtor&分配操作员被提供,如果不是由班级作家提供的 2)虚拟指针和虚拟表格设置正确 3)资源分配,如果有一些指针 – Amar

+0

顺便说一句,这不是一个真实的采访情景,一种方式:) – Amar

7

从技术上讲,你的解释是准确的。没有成员可以从ctor机构内部初始化;只在ctor-initializerctor正文中的任何成员访问权限只能分配。

在输入ctor正文之前,所有成员都被“初始化”。

然而,说起来更广泛地说,因为身体始终遵循的初始化,它说,作为—一旦—构造已结束对象初始化一个单元......包括身体。

部分原因是,从广义上讲,您可能会考虑初始化以包含您必须在您的ctor正文中执行的业务逻辑,尽管这与实际初始化数据成员不同。

+0

这里的初始化究竟意味着什么?例如:'struct X {int a,b; X(int c):a(c){b = c + 1;}',什么时候被初始化? –

+2

@logic:'b'在大括号之前被*初始化*。之后,这只是一种调整。 – Xeo

+0

@Xeo感谢您的清除。 –

1

有关初始化列表的主要内容是效率和代码可读性。

可读性部分是不言自明的,因为您知道在哪里查看值的初始化位置。节约效率是因为如果你在构造函数的代码中为它们赋值,那么它们将被赋值两次:首先当对象被创建时,它们将被分配由该数据类型的默认构造函数提供的值,然后它们将在你的对象的构造函数中被分配一个新的值。初始化列表只是确保它们以您指定的值初始化。

例如,下面是我在一个双向链表实现所使用的初始化列表的例子:

template <typename T> 
LinkedList<T>::LinkedList() 
: size(0) 
, pHead(NULL) 
, pTail(NULL) 
{ 
} 

尽管效率较低的版本,其中大小,PHEAD和PTAIL得到分配如下两次:

template <typename T> 
LinkedList<T>::LinkedList() 
{ 
    size = 0; 
    pHead = NULL; 
    pTail = NULL; 
} 
0

初始值设定项列表是构造函数的一部分。每个构造函数都有自己的。

1

本质上,你是正确的,但不应将成员初始值设定项视为与构造函数分开。初始化程序是构造函数的一部分,并在构造函数的主体之前调用。

当您声明内置类型的自动变量时,它既是定义也是声明。这是一个声明,因为标识符绑定到一个类型,并且它是一个定义,因为编译器为它分配存储空间。

int var1; // declares/defines var of type int 

int var2 = 0; // declares/defines a var of type int and initializes it to 0 

初始化程序在定义初始值时设置初始值,但在初始化程序之前已经定义初始值。

int x = 5; 
int y = 5; 

int main() 
{ 
    int x = x; // x is undefined here not 5 because x refers to itself 
    int y[y]; 
    int size = sizeof(y)/sizeof(int); // size is 5 (y[5]) since y isn't defined until after the enclosing bracket so y referred to the global y in the declaration. 
} 

有一些变量必须然而初始化。常量和参考。

这与构造函数相同。成员的定义就在委员会主体之前。这是调用构造函数时成员和基础的定义顺序。

  1. 虚基类
  2. 基类
  3. 部件 - 在它们被宣布
  4. 构造函数体执行

离开构造体后的顺序,一切都已初始化。

如果你不使用初始值设定项,那么你可以假定它已经在进入ctor体时已经定义了,但是你不能认为它有任何特定的值。同样,常量和引用必须在成员初始化程序中初始化。