冒号运算符(“:”)在这个构造函数中做了什么?它等同于MyClass(m_classID = -1, m_userdata = 0);
吗?
class MyClass {
public:
MyClass() : m_classID(-1), m_userdata(0) {
}
int m_classID;
void *m_userdata;
};
答案 0 :(得分:89)
这是初始化列表,是构造函数实现的一部分。
构造函数的签名是:
MyClass();
这意味着可以在没有参数的情况下调用构造函数。这使它成为默认构造函数,即在编写MyClass someObject;
时默认调用的构造函数。
部分: m_classID(-1), m_userdata(0)
称为初始化列表。这是一种使用您选择的值初始化对象的某些字段(所有这些字段,如果需要)的方法,而不是将它们保留为未定义。
执行初始化列表后,执行构造函数体(在您的示例中恰好为空)。在其中你可以做更多的任务,但是一旦你输入了它,所有的字段都已经被初始化 - 要么是随机的,未指定的值,要么是你在初始化列表中选择的那些。这意味着您在构造函数体中执行的赋值不会是初始化,而是值的更改。
答案 1 :(得分:41)
这是一个初始化列表。
当你进入构造函数的主体时,所有字段都已构建;如果他们有默认的构造函数,那些已经被调用。现在,如果在构造函数的主体中为它们赋值,则调用复制赋值运算符,这可能意味着如果对象具有任何资源,则释放和重新获取资源(例如,内存)。
因此,在原始类型(如int)的情况下,与在构造函数体中分配它们相比没有任何优势。对于具有构造函数的对象,它是性能优化,因为它避免了通过两个对象初始化而不是一个。
如果其中一个字段是引用,则必须使用初始化列表,因为引用永远不能为null,即使在对象构造和构造函数体之间的短暂时间内也是如此。以下引发错误C2758:'MyClass :: member_':必须在构造函数base / 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_;
};
答案 2 :(得分:2)
它表示初始化列表的开头,用于初始化对象的成员变量。
关于:MyClass(m_classID = -1, m_userdata = 0);
声明了一个可以接受参数的构造函数(因此我可以使用MyClass
创建MyClass m = MyClass(3, 4)
,这会导致m_classID
为3,m_userdata
为4) 。如果我不向MyClass
构造函数传递任何参数,则会导致为具有初始化列表的版本创建等效对象。
答案 3 :(得分:2)
它表示初始化列表的开头。
它也不等同于MyClass(m_classId = -1,m_userData = 0)。这是尝试定义具有2个具有默认值的参数的构造函数。但是,值缺少类型,根本不应该编译。
答案 4 :(得分:1)
这是一个initialization list。在你的例子中,它更像是这样的东西(这样的东西 - 并不意味着它在所有情况下都是等价的):
class MyClass {
public:
MyClass(){
m_classID = -1;
m_userdata = 0;
}
int m_classID;
void *m_userdata;
};
答案 5 :(得分:1)
这称为成员初始化列表。它用于调用超类constrctors,并在创建它们时为您的成员变量赋予初始值。
在这种情况下,它将m_classID
初始化为-1,将m_userData
初始化为NULL。
它不等同于在构造函数的主体中赋值,因为后者首先创建成员变量,然后分配给它们。通过初始化,初始值在创建时提供,因此在复杂对象的情况下,它可以更有效。
答案 6 :(得分:1)
这不是一个操作员。它是构造函数语法的一部分。
它的含义是跟随它将是成员变量及其初始值的列表。
必须以这种方式初始化常量成员。非常量也可以在这里初始化,只要它可以用单个表达式完成。如果初始化成员需要的代码多于代码,则必须在{}之间放置实际代码才能执行此操作。
很多人都喜欢将所有构造函数代码放在initilizer列表中。我有一个同事经常用几个启动器屏幕编写类,然后为构造函数代码添加“{}”。
答案 7 :(得分:1)
它是初始化列表的开始,它在构造对象期间设置成员变量。你的例子“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;
}
谷歌了解更多信息。
答案 8 :(得分:0)
在这种情况下:是的,ist是等价的,因为只涉及原始类型。
如果成员是类(结构),那么您应该更喜欢初始化列表。这是因为否则默认构造对象,然后分配对象。