C ++构造函数名称后面的冒号是做什么的?
这个冒号运算符(“:”)在这个构造函数中做什么? 它相当于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;
时候默认会调用它MyClass someObject;
。
部分: m_classID(-1), m_userdata(0)
被称为初始化列表 。 这是一种方法来初始化您的对象的一些领域(所有这些,如果你想)与您select的价值观,而不是把它们留在未定义。
执行初始化列表后,执行构造函数体(在你的例子中是空的)。 在里面你可以做更多的任务,但是一旦你input了,所有的字段都已经被初始化 – 或者是随机的,未指定的值,或者是你在初始化列表中select的值。 这意味着你在构造函数体中的赋值不会是初始化,而是值的变化。
这是一个初始化列表。
当你进入build设者的身体,所有的领域已经build成; 如果他们有默认的构造函数,那些已经被调用。 现在,如果在构造函数的主体中为它们赋值,则调用复制赋值操作符,如果对象有任何操作符,则可能意味着释放和重新获取资源(如内存)。
所以在像int这样的基本types的情况下,与在构造函数中分配它们相比,没有什么优势。 在具有构造函数的对象的情况下,这是性能优化,因为它避免了两个对象初始化而不是一个。
如果其中一个字段是引用,则初始化列表是必需的,因为引用永远不能为空,即使在对象构造和构造函数主体之间的短暂时间内也是如此。 以下引发错误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_; };
它表示初始化列表的开始,它用于初始化对象的成员variables。
至于: MyClass(m_classID = -1, m_userdata = 0);
这声明了一个可以带参数的构造函数(所以我可以使用MyClass m = MyClass(3, 4)
创build一个MyClass
,这将导致m_classID
为3, m_userdata
为4)。 如果我不向MyClass
构造函数传递参数,那么会导致与初始化列表一起为该版本创build一个等效对象。
它表示初始化列表的开始。
它也不等于MyClass(m_classId = -1,m_userData = 0)。 这是试图定义一个具有2个参数,具有默认值的构造函数。 然而,价值观缺乏types,根本不应该编译。
这是一个初始化列表 。 在你的例子中,它是这样的(像这样的东西 – 并不意味着它在所有情况下是等价的):
class MyClass { public: MyClass(){ m_classID = -1; m_userdata = 0; } int m_classID; void *m_userdata; };
这被称为成员初始化列表 。 它被用来调用超类的构造器,并且在创build时给你的成员variables一个初始值。
在这种情况下,它将m_classID
初始化为-1,将m_userData
初始化为NULL。
它不等同于在构造函数体中赋值,因为后者首先创build成员variables,然后赋值给它们。 初始化时,初始值是在创build时提供的,所以在复杂对象的情况下可以更高效。
这不完全是一个运营商。 这是构造函数的语法的一部分。
它所说的是,接下来是成员variables列表和它们的初始值。
常量成员必须以这种方式进行初始化。 非常量也可以在这里初始化,只要它可以用一个expression式来完成。 如果需要比初始化成员更多的代码,则必须将实际代码放在{}之间。
很多人喜欢把他们所有的构造函数代码放在initilizer列表中。 我有一个经常用类似于initilizers的屏幕编写类的同事,然后把“{}”作为构造函数代码。
它是在构造对象期间设置成员variables的初始化列表的开始。 你的例子“MyClass(m_classID = -1,m_userdata = 0);” 是不可能的,因为你还没有定义正确的构造函数,你将无法访问参数列表中的成员variables…你可能有这样的东西:
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是相等的,因为只涉及原始types。
如果成员是类(结构),那么你应该更喜欢初始化列表。 这是因为否则对象是默认构造,然后分配。