我读“加速C ++”,由安德鲁·柯尼希和Barbara E.武,和我在有关构造函数的章节(5.1)。
他们在这里指出
我们说构造器是存在,确保对象是在一个合理的状态,它们的数据成员创建的。 在一般情况下,这样的设计目标,意味着每一个构造函数应该初始化所有的数据成员。 需要给成员的值是内置类型的成员尤其重要。 ...
虽然我们explicityly只初始化midterm
和final
,其他数据成员被隐式初始化。 具体而言, n
由初始化string
默认的构造,和homework
由初始化vector
默认构造函数。
他们谈论的是类
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;
};
和他们的默认构造函数是
Student_info::Student_info(): midterm(0), final(0) {}
我只是想澄清,这意味着物像int
和double
那里是没有std::
之前术语将需要专门初始化?
那是对的。
但是,性病::是不是你在找什么。
任何基本类型的,除非你做它明确不被初始化。
所以char/int/float/pointers
等。而且任何类/联合(如通过下面伊恩说明)没有明确的构造将默认初始化其成员(这意味着基本(和递归类的成员S /工会没有和显式构造)他们没有定义)。
旁注:
- 此规则适用于自动和动态存储持续时间对象
- 静态和线程存储时限的对象初始化为零。
int
和double
是内置的类型,而不是类,所以他们没有默认的构造函数,默认情况下是不确定的。 例如:
int a;
Student_info s;
两个变量的语法是相同的,但值a
未定义,而值s
被定义,因为Student_info s
实际调用的构造,即, Student_info s = Student_info();
。
笔者只是想表明的一切是默认为0的等效字符串与矢量默认的构造函数,这些也只是空的。 对于基本类型,如int和双,这些原语的声明在初始值默认为这是在存储器变量指向的值。 这不依赖于编译器,虽然
这是不相关的std名字空间。 n和功课是类,其构造函数将Student_info施工过程中被调用。 但是,期中和期末的是原始值,有没有为他们构造。 在初始化构造函数中的原始成员是没有必要的,但一个好的方式。
还有更多的东西。
1)对于基本或内置类型, 隐含地初始化(或编译器初始化)指无操作(什么也不做)。
2)对于原始或内置类型, 明确地初始化(或由程序员初始化)是显而易见的:)
作为你的例子:
Student_info::Student_info(): midterm(0), final(0) {}
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)对于非原始类型, 明确地初始化(或由用户提供的构造初始化)指编译器会使得对用户定义的构造,而不是合成一个用于初始化的目的呼叫。
例如,由相应的非原始类型定义(像的std :: string或std ::向量)默认构造被调用。
**
注:编译器仍然可以增加用户定义的构造函数中的代码做一些幕后的初始化如需要时(看步-3以上的这样的需求)。 这种增强的代码将永远在构造函数中的用户定义的代码之前插入!
**