这个问题已经在这里有一个答案:
- 这是什么奇怪的冒号成员(“:”)语法在构造函数? 12个回答
什么是冒号运算符(“:”)在此构造吗? 是它等同于MyClass(m_classID = -1, m_userdata = 0);
?
class MyClass {
public:
MyClass() : m_classID(-1), m_userdata(0) {
}
int m_classID;
void *m_userdata;
};
这个问题已经在这里有一个答案:
什么是冒号运算符(“:”)在此构造吗? 是它等同于MyClass(m_classID = -1, m_userdata = 0);
?
class MyClass {
public:
MyClass() : m_classID(-1), m_userdata(0) {
}
int m_classID;
void *m_userdata;
};
这是一个初始化列表 ,是构造函数的实现的一部分。
构造函数的签名是:
MyClass();
这意味着,构造函数可以不带参数调用。 这使得一个默认的构造 ,即,其中一个将被默认调用的时候你写MyClass someObject;
。
该部分: m_classID(-1), m_userdata(0)
被调用初始化列表 。 它与您选择的值来初始化,而不是让他们为未定义的对象(所有的人,如果你想)的某些领域,方式。
执行初始化列表后,构造函数体被执行(这恰好是在你的例子是空的)。 它里面你可以做更多的任务,但一旦你进入它所有的领域都已经被初始化 - 无论是随机的,未指定的值,或在您的初始化列表中选择的人。 这意味着你在构造函数体做不会初始化的任务,但值的变化。
这是一个初始化列表。
通过你在构造函数的身体得到的时候,各个领域已经建立; 如果他们有默认的构造函数,那些已经被调用。 现在,如果你在构造函数体内赋值给他们,您呼叫的拷贝赋值运算符,这可能意味着释放和重新获取资源(例如内存)如果对象有什么。
因此,在基本类型如int的情况下,还有比在构造函数体赋予它们没有什么优势。 在具有构造对象的情况下,它是一种性能优化,因为它避免了通过两个对象初始化,而不是一个会。
一个初始化列表是必要的,如果其中一个字段是一个参考,因为一个参考不能为空,即使是在对象构造与构造体之间的短暂时间。 下面会引发错误C2758:“MyClass的:: member_”:必须构造基地进行初始化/成员初始化列表
class MyClass {
public :
MyClass(std::string& arg) {
member_ = arg;
}
std::string& member_;
};
唯一正确的方法是:
class MyClass {
public :
MyClass(std::string& arg)
: member_(arg)
{
}
std::string& member_;
};
它表示初始化器列表,这是您的初始化对象的成员变量的开始。
至于: MyClass(m_classID = -1, m_userdata = 0);
声明可以取参数的构造函数(所以我可以创建一个MyClass
使用MyClass m = MyClass(3, 4)
这将导致在m_classID
为3,和m_userdata
为4)。 如果我没有参数传递给MyClass
构造函数,这将导致等同对象被创建与初始化器列表的版本。
它标志着一个初始化列表的开头。
此外,它不等于MyClass的(m_classId = -1,m_userData = 0)。 这是试图定义有两个参数有默认值的构造函数。 然而,缺乏值类型和它不应该编译的。
这是一个初始化列表 。 在您的例子,它是相当像这样(像这样 - 并不意味着它在所有情况下的等价物):
class MyClass {
public:
MyClass(){
m_classID = -1;
m_userdata = 0;
}
int m_classID;
void *m_userdata;
};
这就是所谓的成员初始化列表 。 它是用来调用父类constrctors,并给你的成员变量在它们被创建时的初始值。
在这种情况下,初始化m_classID
-1和m_userData
为NULL。
这是不太相当于在构造函数体内分配,因为后者首先创建成员变量,然后分配给他们。 随着初始化,初始值是在创建时提供,所以在复杂的对象的情况下,它可以是更有效的。
这不正是运营商。 它的语法构造的一部分。
它是什么想说的是,以下将是成员变量和初始值的列表。
恒成员有这样的方法来初始化。 非常量可以在这里过,只要它可以用一个表达式来进行初始化。 如果需要更多的代码比初始化一个成员,你必须把之间的实际代码{}的做到这一点。
很多人喜欢把相当多的initilizer列表中的所有构造函数的代码。 我有一个同事谁定期与initilizers的几个屏幕写入类,并提出“{}”的构造函数代码。
它该对象的构造过程中设置的成员变量的初始化器列表的开始。 您的示例 “MyClass的(m_classID = -1,m_userdata = 0);” 是不可能的,因为你还没有定义正确的构造函数,你将无法访问成员变量参数列表反正...你可以有这样的:
MyClass( int classId = -1, void* userData = 0 ) : m_classID(classId), m_userdata(userData) {}
在初始化器列表被认为优于:
MyClass( int classId = -1, void* userData = 0 ) {
m_classID = classId;
m_userdata = userData;
}
谷歌获得更多信息。
在这种情况下:是的,IST因为只有原始类型关注等同。
如果成员是类(结构),那么你应该更喜欢初始化列表。 这是因为否则的对象是默认的构造,然后分配。