简体   繁体   English

构造函数初始化

[英]Constructor initialization

I am reading "Accelerated C++" by Andrew Koenig and Barbara E. Moo, and I'm at the chapter about constructors (5.1). 我正在阅读Andrew Koenig和Barbara E. Moo撰写的“ Accelerated C ++”,并且我正在讨论有关构造函数(5.1)的章节。

They mention here that 他们在这里提到

We said that constructors exist to ensure that objects are created with their data members in a sensible state. 我们说过,构造函数的存在是为了确保在其数据成员处于合理状态下创建对象。 In general, this design goal means that every constructor should initialize every data member. 通常,此设计目标意味着每个构造函数都应初始化每个数据成员。 The need to give members a value is especially critical for members of built-in type. 对于内置类型的成员,赋予成员一个值特别重要。 ... ...

Although we explicityly initialized only midterm and final , the other data members are initialized implicitly. 尽管我们仅对midtermfinal了显式初始化,但其他数据成员也进行了隐式初始化。 Specifically, n is initialized by the string default constructor, and homework is initialized by the vector default constructor. 具体来说, nstring默认构造函数初始化, homeworkvector默认构造函数初始化。

The class they are talking about is 他们正在谈论的课程是

class Student_info {
public:
    std::string name() const (return n;}
    bool valid() const {return !homework.empty();}
    std::istream& read(std::istream&);

    double grade() const;
private:
    std::string n;
    double midterm, final;
    std::vector<double> homework;
};

and their default constructor is 他们的默认构造函数是

Student_info::Student_info(): midterm(0), final(0) {}

I would just like to clarify that this means that things like int and double where there isn't a std:: before the term will need to be initialized specifically? 我只想澄清一下,这意味着像intdouble这样在没有std:: ,需要专门初始化该术语之前?

That is correct. 那是对的。
But std:: is not what you are looking for. 但是std ::不是您想要的。

Any of the fundamental types are not initialized unless you do it explicitly. 除非您显式进行初始化,否则任何基本类型都不会初始化。

So char/int/float/pointers etc. Also (as noted by Ian below) any class/unions without an explicit constructor will default initialize its members (which means fundamental (and recursively for member s of class/unions without and explicit constructor) that they are left undefined). 因此, char/int/float/pointers等。此外(如下面的Ian所述),没有显式构造函数的任何类/联合将默认初始化其成员(这意味着基本的(并且对于不具有显式构造函数的类/联合的成员s)他们未定义)。

A side note: 旁注:

  • This rules applies to automatic and dynamic storage duration objects 此规则适用于自动和动态存储期限对象
  • Static and thread storage duration objects are zero initialized. 静态和线程存储持续时间对象初始化为零。

int and double are built-in types, not classes, so they don't have default constructors, and are undefined by default. intdouble是内置类型,而不是类,因此它们没有默认的构造函数,并且默认情况下未定义。 For example: 例如:

int a;
Student_info s;

The syntax for both variables is the same, but the value of a is undefined, while the value of s is defined because Student_info s actually calls the constructor, ie Student_info s = Student_info(); 两个变量的语法是相同的,但值a未定义,而值s被定义,因为Student_info s实际调用的构造,即, Student_info s = Student_info(); .

The author is just trying to show a default constructor where everything is defaulted to the equivalent of 0. For string and vector, those will just be empty. 作者只是试图显示一个默认构造函数,其中所有默认值都等于0。对于字符串和向量,这些将为空。 For primitive types such as int and double, the initial value of these primitives during declaration is defaulted to the value that was in memory that variable points to. 对于int和double之类的基本类型,在声明过程中这些基本类型的初始值默认为变量所指向的内存中的值。 This does depend on the compiler though 这确实取决于编译器

It is not related to std namespace. 它与std名称空间无关。 n and homework are classes, their constructor will be called during the construction of Student_info. n和家庭作业是类,在构造Student_info时将调用它们的构造函数。 But midterm and final are primitive values, there aren't constructors for them. 但是midterm和final是原始值,没有针对它们的构造函数。 Initialize the primitive member in constructor is not necessary but a good manner. 在构造函数中初始化基本成员不是必需的,而是一种好方法。

There is more to it. 还有更多。

1) For primitive or built-in types, implicitly initialized (or compiler initialized) means no-op (does nothing). 1)对于原始或内置类型, 隐式初始化(或编译器初始化)表示无操作(不执行任何操作)。

2) For primitive or built-in types, explicitly initialized (or initialized by the programmer) is obvious :) 2)对于原始或内置类型, 显式初始化(或由程序员初始化)很明显:)

As in your example: 如您的示例:

    Student_info::Student_info(): midterm(0), final(0) {}

3) For non-primitive types, implicitly initialized (or compiler initialized) means compiler may (or may not) synthesis a constructor for the purpose of initialization. 3)对于非原始类型, 隐式初始化(或编译器初始化)意味着编译器可以(也可以不)为初始化目的而合成构造函数。

  Usually, a constructor is synthesized by the compiler under the following cases: a) The non-primitive type is polymorphic or derives from some polymorphic/non-polymorphic types, b) The non-primitive type has a polymorphic/non-polymorphic member. Compiler synthesized constructor will usually have code to a) initialize v-pointer to v-table, b) call base class constructor, c) call constructors of members, so on, basically driven by the definition of non-primitive type. 

4) For non-primitive types, explicitly initialized (or initialized by the user supplied constructor) means compiler would make a call to the user defined constructor instead of synthesizing one for the purpose of initialization. 4)对于非原始类型, 显式初始化(或由用户提供的构造函数初始化)意味着编译器将调用用户定义的构造函数,而不是出于初始化目的而合成一个。

For example, the default constructor defined by the respective non-primitive types (like std::string or std::vector) gets invoked. 例如,将调用由各个非基本类型(例如std :: string或std :: vector)定义的默认构造函数。

** **

Note: Compiler may still augment code inside the user-defined constructor to do some behind-the-scenes initialization as need be (look at step-3 above for such needs). 注意:编译器可能仍会根据需要在用户定义的构造函数内扩展代码,以进行一些幕后初始化(有关此类需求,请参见上面的第3步)。 Such augmented code will always be inserted before the user-defined code inside the constructor! 这样的扩充代码将始终插入到构造函数中用户定义的代码之前!

** **

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM