在内部和生成的代码之间,真的有区别:
MyClass::MyClass(): _capacity(15), _data(NULL), _len(0)
{
}
和
MyClass::MyClass()
{
_capacity=15;
_data=NULL;
_len=0
}
谢谢...
Answers:
假设这些值是原始类型,则没有差异。初始化列表仅在将对象作为成员时才有所不同,因为初始化列表使您可以将对象初始化为其最终值,而不是使用默认初始化后再进行赋值。实际上,这实际上可以更快。
您需要使用初始化列表来初始化常量成员,引用和基类
如注释中所述,当需要初始化常量成员,引用并将参数传递给基类构造函数时,需要使用初始化列表。
struct aa
{
int i;
const int ci; // constant member
aa() : i(0) {} // will fail, constant member not initialized
};
struct aa
{
int i;
const int ci;
aa() : i(0) { ci = 3;} // will fail, ci is constant
};
struct aa
{
int i;
const int ci;
aa() : i(0), ci(3) {} // works
};
示例(非穷举)类/结构包含参考:
struct bb {};
struct aa
{
bb& rb;
aa(bb& b ) : rb(b) {}
};
// usage:
bb b;
aa a(b);
初始化需要参数的基类的示例(例如,没有默认构造函数):
struct bb {};
struct dd
{
char c;
dd(char x) : c(x) {}
};
struct aa : dd
{
bb& rb;
aa(bb& b ) : dd('a'), rb(b) {}
};
_capacity
,_data
并_len
有一流的类型,而一个可访问的默认构造?
const
在构造函数的主体中初始化成员,而必须使用初始化列表-非const
成员可以在初始化列表或构造函数的主体中进行初始化。
是。在第一种情况下,你可以声明_capacity
,_data
并_len
为常量:
class MyClass
{
private:
const int _capacity;
const void *_data;
const int _len;
// ...
};
如果要const
在运行时计算它们的值时确保这些实例变量的-ness属性,这将非常重要,例如:
MyClass::MyClass() :
_capacity(someMethod()),
_data(someOtherMethod()),
_len(yetAnotherMethod())
{
}
const
实例必须在初始化列表中初始化,或者基础类型必须提供公共的无参数构造函数(原始类型可以做到)。
我认为此链接http://www.cplusplus.com/forum/articles/17820/提供了很好的解释-特别是对于那些C ++新手。
初始化程序列表更有效的原因是,在构造函数主体内,仅发生分配,而不进行初始化。因此,如果要处理的是非内置类型,则在输入构造函数的主体之前,已调用该对象的默认构造函数。在构造函数主体内,您正在为该对象分配一个值。
实际上,这是对默认构造函数的调用,然后是对复制分配运算符的调用。初始化程序列表使您可以直接调用复制构造函数,这有时可能会明显更快(请注意,初始化程序列表位于构造函数的主体之前)
我要补充一点,如果您有没有默认构造函数的类类型成员,则初始化是构造类的唯一方法。
初始化基类实例和非静态成员变量的方法只有一种,那就是使用初始化程序列表。
如果未在构造函数的初始值设定项列表中指定基本或非静态成员变量,则该成员或基本将被默认初始化(如果成员/基本是非POD类类型或非POD类数组)类型),否则不进行初始化。
输入构造函数主体后,所有基数或成员将已初始化或未初始化(即,它们将具有不确定的值)。构造函数主体中没有机会影响应如何初始化它们。
您可能能够向构造函数主体中的成员分配新值,但无法将其分配给不可分配的const
成员或类类型的成员,并且无法重新绑定引用。
对于内置类型和某些用户定义的类型,在构造函数主体中进行分配可能与使用初始化列表中的相同值进行初始化具有完全相同的效果。
如果您无法在初始化器列表中命名成员或基础,并且该实体是引用,具有没有用户可访问的用户声明的默认构造函数的const
类类型,则该类型合格且具有POD类型,或者是POD类类型或POD类类型的数组包含const
合格成员(直接或间接),则程序格式不正确。
构造函数中的初始化列表和初始化语句之间有区别。让我们考虑下面的代码:
#include <initializer_list>
#include <iostream>
#include <algorithm>
#include <numeric>
class MyBase {
public:
MyBase() {
std::cout << __FUNCTION__ << std::endl;
}
};
class MyClass : public MyBase {
public:
MyClass::MyClass() : _capacity( 15 ), _data( NULL ), _len( 0 ) {
std::cout << __FUNCTION__ << std::endl;
}
private:
int _capacity;
int* _data;
int _len;
};
class MyClass2 : public MyBase {
public:
MyClass2::MyClass2() {
std::cout << __FUNCTION__ << std::endl;
_capacity = 15;
_data = NULL;
_len = 0;
}
private:
int _capacity;
int* _data;
int _len;
};
int main() {
MyClass c;
MyClass2 d;
return 0;
}
使用MyClass时,将在执行构造函数中的第一条语句之前初始化所有成员。
但是,当使用MyClass2时,执行构造函数中的第一条语句时不会初始化所有成员。
在以后的情况下,当有人在初始化某个成员之前在构造函数中添加了一些代码时,可能会出现回归问题。