1

我正在阅读 Andrew Koenig 和 Barbara E. Moo 的“Accelerated C++”,我正在阅读关于构造函数(5.1)的章节。

他们在这里提到

我们说过构造函数的存在是为了确保创建对象时其数据成员处于合理状态。一般来说,这个设计目标意味着每个构造函数都应该初始化每个数据成员。给成员一个值的需要对于内置类型的成员来说尤其重要。...

虽然我们只显式地初始化了midtermfinal,但其他数据成员被隐式初始化。具体来说,nstring默认构造函数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东西?doublestd::

4

5 回答 5

3

那是对的。
但 std:: 不是你要找的。

除非您明确地进行初始化,否则任何基本类型都不会被初始化。

等等char/int/float/pointers。另外(如下面的 Ian 所指出的)任何没有显式构造函数的类/联合都将默认初始化其成员(这意味着基本的(并且对于没有显式构造函数的类/联合的成员,它们是未定义的)。

旁注:

  • 此规则适用于自动和动态存储期限对象
  • 静态和线程存储持续时间对象初始化为零。
于 2013-03-22T06:50:02.333 回答
2

int并且double是内置类型,而不是类,因此它们没有默认构造函数,并且默认情况下未定义。例如:

int a;
Student_info s;

两个变量的语法是相同的,但是 的值a是未定义的,而 的值s是定义的,因为Student_info s实际上调用了构造函数,即Student_info s = Student_info();

于 2013-03-22T06:48:15.160 回答
1

作者只是试图显示一个默认构造函数,其中所有内容都默认为等效于 0。对于字符串和向量,它们将是空的。对于 int 和 double 等原始类型,这些原始类型在声明期间的初始值默认为变量指向的内存中的值。这确实取决于编译器

于 2013-03-22T06:49:01.963 回答
1

它与 std 命名空间无关。n 和 homework 是类,它们的构造函数会在 Student_info 的构建过程中被调用。但是 midterm 和 final 是原始值,它们没有构造函数。在构造函数中初始化原始成员不是必需的,而是一种好的方式。

于 2013-03-22T06:50:21.260 回答
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 了解此类需求)。这样的增强代码将始终插入到构造函数内的用户定义代码之前!

**

于 2013-03-22T07:24:47.037 回答