我正在阅读"加速C ++"作者:Andrew Koenig和Barbara E. Moo,以及关于构造函数的章节(5.1)。
他们在这里提到
我们说构造函数的存在是为了确保创建对象的数据成员处于合理状态。通常,此设计目标意味着每个构造函数都应初始化每个数据成员。为内置类型的成员提供值的需求尤其重要。 ...
虽然我们只是明确地初始化了
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::
需要专门初始化?
答案 0 :(得分:3)
这是正确的。
但是std ::不是你想要的。
除非您明确地执行此操作,否则不会初始化任何基本类型。
所以char/int/float/pointers
等。另外(如下面的Ian所述)任何没有显式构造函数的类/联合都将默认初始化其成员(这意味着基本的(并且对于没有和显式构造函数的类/联合的成员的递归) )它们未定义)。
旁注:
答案 1 :(得分:2)
int
和double
是内置类型,而不是类,因此它们没有默认构造函数,默认情况下未定义。例如:
int a;
Student_info s;
两个变量的语法相同,但a
的值未定义,而s
的值是定义的,因为Student_info s
实际上调用了构造函数,即{{1 }}
答案 2 :(得分:1)
作者只是试图显示一个默认构造函数,其中所有内容默认为等效于0.对于字符串和向量,这些只是空的。对于诸如int和double之类的基本类型,声明期间这些基元的初始值默认为变量所指向的内存中的值。这确实取决于编译器
答案 3 :(得分:1)
它与std命名空间无关。 n和家庭作业是类,他们的构造函数将在构建Student_info期间被调用。但是期中和期末都是原始价值,没有建设者。在构造函数中初始化原始成员不是必要的,但是很好。
答案 4 :(得分:0)
还有更多内容。
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 :: vector)定义的默认构造函数。
**
注意:编译器仍然可以在用户定义的内部扩充代码 构造函数根据需要做一些幕后初始化 (请看上面的第3步,了解这些需求)。这样的增强代码将始终如此 在构造函数内的用户定义代码之前插入!
**