C++ 后面的冒号代表什么? 构造函数名称呢?

发布于 2024-08-01 13:32:17 字数 242 浏览 10 评论 0原文

冒号运算符(“:”)在此构造函数中起什么作用? 它是否相当于MyClass(m_classID = -1, m_userdata = 0);

class MyClass {
public:

    MyClass() : m_classID(-1), m_userdata(0) { 
    }

    int m_classID;
    void *m_userdata;
};

What does the colon operator (":") do in this constructor? Is it equivalent to MyClass(m_classID = -1, m_userdata = 0);?

class MyClass {
public:

    MyClass() : m_classID(-1), m_userdata(0) { 
    }

    int m_classID;
    void *m_userdata;
};

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

守望孤独 2024-08-08 13:32:17

它标志着初始化列表的开始。

它也不等同于 MyClass(m_classId=-1,m_userData=0)。 这是尝试定义一个带有 2 个具有默认值的参数的构造函数。 然而,这些值缺乏类型,根本不应该编译。

It signals the beginning of an initializer list.

Also it is not equivalent to MyClass(m_classId=-1,m_userData=0). This is attempting to define a constructor with 2 parameters that have default values. However the values lack types and it should not compile at all.

巾帼英雄 2024-08-08 13:32:17

这是一个成员初始值设定项列表,并且是构造函数实现的一部分。

构造函数的签名是:

MyClass();

这意味着可以不带参数调用构造函数。 这使得它成为一个默认构造函数,即当您编写MyClass someObject;时默认调用的构造函数。

: m_classID(-1), m_userdata(0) 部分称为成员初始值设定项列表。 这是一种用您选择的值初始化对象的某些字段(如果需要的话,可以全部初始化)的方法。

执行成员初始值设定项列表后,将执行构造函数主体(在您的示例中恰好为空)。 在其中您可以做更多的分配,但是一旦您输入它,所有字段都已经被初始化 - 要么是随机的、未指定的值,要么是您在初始化列表中选择的值。 这意味着您在构造函数主体中所做的分配将不是初始化,而是值的更改。

This is a member initializer list, and is part of the constructor's implementation.

The constructor's signature is:

MyClass();

This means that the constructor can be called with no parameters. This makes it a default constructor, i.e., one which will be called by default when you write MyClass someObject;.

The part : m_classID(-1), m_userdata(0) is called member initializer list. It is a way to initialize some fields of your object (all of them, if you want) with values of your choice.

After executing the member initializer list, the constructor body (which happens to be empty in your example) is executed. Inside it you could do more assignments, but once you have entered it all the fields have already been initialized - either to random, unspecified values, or to the ones you chose in your initialization list. This means the assignments you do in the constructor body will not be initializations, but changes of values.

嗼ふ静 2024-08-08 13:32:17

这是一个初始化列表。

当您进入构造函数主体时,所有字段都已构造完毕; 如果它们有默认构造函数,那么它们已经被调用了。 现在,如果您在构造函数主体中为它们赋值,您将调用复制赋值运算符,这可能意味着释放并重新获取资源(例如内存)(如果对象有任何资源)。

因此,对于像 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_;
};

It is an initialization list.

By the time you get in the body of the constructor, all fields have already been constructed; if they have default constructors, those were already called. Now, if you assign a value to them in the body of the constructor, you are calling the copy assignment operator, which may mean releasing and reacquiring resources (e.g. memory) if the object has any.

So in the case of primitive types like int, there's no advantage compared to assigning them in the body of the constructor. In the case of objects that have a constructor, it is a performance optimization because it avoids going through two object initializations instead of one.

An initialization list is necessary if one of the fields is a reference because a reference can never be null, not even in the brief time between object construction and the body of the constructor. The following raises error C2758: 'MyClass::member_' : must be initialized in constructor base/member initializer list

class MyClass {
public :
    MyClass(std::string& arg) {
        member_ = arg;
    }
    std::string& member_;
};

The only correct way is:

class MyClass {
public :
    MyClass(std::string& arg) 
        : member_(arg) 
    {
    }
    std::string& member_;
};
多彩岁月 2024-08-08 13:32:17

它表示初始化列表的开始,用于初始化对象的成员变量。

至于: MyClass(m_classID = -1, m_userdata = 0);

它声明了一个可以接受参数的构造函数(因此我可以使用 MyClass m 创建一个 MyClass = MyClass(3, 4),这将导致 m_classID 为 3,m_userdata 为 4)。 如果我不向 MyClass 构造函数传递任何参数,则会导致使用初始化列表的版本创建一个等效对象。

It denotes the beginning of an initialiser list, which is for initialising member variables of your object.

As to: MyClass(m_classID = -1, m_userdata = 0);

That declares a constructor which can take arguments (so I could create a MyClass using MyClass m = MyClass(3, 4), which would result in m_classID being 3, and m_userdata being 4). If I were to pass no arguments to the MyClass constructor, it would result in an equivalent object being created to the version with the initialiser list.

星軌x 2024-08-08 13:32:17

这是一个初始化列表。 在你的例子中,它是这样的(这样的东西 - 并不意味着它在所有情况下都是等价的):


class MyClass {

public:

    MyClass(){
         m_classID = -1;
         m_userdata = 0;
    }

    int m_classID;
    void *m_userdata;

};

It's a initialization list. In your example, it's rather something like this (something like this - doesn't mean it's equivalent in all cases):


class MyClass {

public:

    MyClass(){
         m_classID = -1;
         m_userdata = 0;
    }

    int m_classID;
    void *m_userdata;

};
无所谓啦 2024-08-08 13:32:17

它不完全是一个操作符。 它是构造函数语法的一部分。

它的意思是,后面将是成员变量及其初始值的列表。

常量成员必须以这种方式初始化。 非常量也可以在这里初始化,只要它可以用单个表达式完成即可。 如果需要的代码多于初始化成员的代码,则必须在 {} 之间放置实际代码才能完成此操作。

很多人喜欢将几乎所有构造函数代码都放在初始化程序列表中。 我有一位同事经常编写带有多个初始化程序屏幕的类,然后为构造函数代码添加“{}”。

It isn't precisely an operator. It's a part of the syntax for a constructor.

What it is saying is that following it will be a list of member variables and their initial values.

Constant members have to be initialized this way. Non-constants can be initialized here too, as long as it can be done with a single expression. If it takes more code than that to initialize a member, you have to put actual code between the {}'s to do it.

A lot of people like to put pretty much all their constructor code in the initilizer list. I have one co-worker who regularly writes classes with several screens of initilizers, and then puts "{}" for the constructor code.

已下线请稍等 2024-08-08 13:32:17

这称为成员初始化列表。 它用于调用超类构造函数,并在创建成员变量时为其赋予初始值。

在本例中,它将 m_classID 初始化为 -1,将 m_userData 初始化为 NULL。

它并不完全等同于在构造函数主体中赋值,因为后者首先创建成员变量,然后分配给它们。 通过初始化,在创建时提供初始值,因此在复杂对象的情况下,可以更加高效。

That is called the member initialization list. It is used to call the superclass constrctors, and give your member variables an initial value at the time they are created.

In this case, it is initializing m_classID to -1 and m_userData to NULL.

It is not quite equivalent to assigning in the body of the constructor, because the latter first creates the member variables, then assigns to them. With the initialization, the initial value is provided at the time of creation, so in the case of complex objects, it can be more efficient.

熊抱啵儿 2024-08-08 13:32:17

它是初始化列表的开始,该列表在对象的构造过程中设置成员变量。 您的示例“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;
}

Google 获取更多信息更好。

Its the start of an initialiser list which sets member variables during the construction of the object. Your example "MyClass(m_classID = -1, m_userdata = 0);" is not possible as you have not defined the correct constructor and you would not be able to access the member variables in the parameter list anyway... you could have something like:

MyClass( int classId = -1, void* userData = 0 ) : m_classID(classId), m_userdata(userData) {}

The initialiser list is considered better than:

MyClass( int classId = -1, void* userData = 0 ) {
    m_classID = classId;
    m_userdata = userData;
}

Google for more info.

长亭外,古道边 2024-08-08 13:32:17

在这种情况下: 是的,ist 是等价的,因为只涉及原始类型。

如果成员是类(结构),那么您应该更喜欢初始化列表。 这是因为否则对象将被默认构造然后分配。

In this case: Yes, ist is equivalent because only primitive types are concerned.

If the members are classes (structs) then you should prefer the initialization list. This is because otherwise the objects are default constructed and then assigned.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文