3.5.1 构造函数
构造函数是一种与类名相同的成员函数。当我们创建类的一个实例时(例如,定义一个类的变量时)就会自动地调用某个合适的构造函数。
例3-19
本例声明了一个Person类,拥有一个私有数据成员和六个公有成员函数,其中的三个成员函数是构造函数:
这些成员函数都有着与类相同的名称:Person,而且没有返回类型。构造函数不能有返回类型,因此如下声明是错误的:
如例3-19所示,一个类可以拥有多个构造函数,也就是说,可以对构造函数进行重载。但每个构造函数必须拥有各不相同的函数署名(见2.6节)。在例3-19中,三个构造函数的函数署名各不相同:第一个没有参数,第二个的参数类型为const string引用,第三个的参数类型为C风格字符串:const char*。
例3-20
本例列举了如何使用例3-19中定义的两个构造函数。通过定义anonymous对象,导致默认构造函数(default constructor)被调用。默认构造函数是不带任何参数的构造函数。其他构造函数称为带参构造函数(parameterized constructors)。jc的定义语句
看上去就像一个带有单个参数的函数。实际上,jc是Person类型的一个变量。该语法通知编译器使用参数J. Coltrane调用Person类的某个合适的带参构造函数以初始化变量jc。
当创建一个对象时,构造函数会被调用。构造函数为类提供了一个特殊的成员函数,此函数在创建对象时自动被调用。总之,程序员不需要调用构造函数。构造函数主要用来对数据成员进行初始化,并负责其他一些在对象创建时需要处理的事务。构造函数对提高类的健壮性有着重要作用。
例3-21
3.2节中,Stack类没有构造函数。为保证一个Stack正确运行,top成员必须初始化为-1。虽然3.2节中的Stack版本提供了init成员函数来完成这个初始化任务,但程序员可能会在创建一个Stack对象之后忘了调用init成员函数:
上述代码中,top没有进行适当的初始化,因此其初值是未定的。我们可以通过为Stack类增加一个默认构造函数来解决这个问题:
上述代码中,默认构造函数调用了init成员函数,这样当定义一个Stack对象(如s1)时,编译器自动调用其默认构造函数,默认构造函数再调用init成员函数。
构造函数最大的特点是:函数名与类名相同,没有返回类型。除此之外,构造函数的行为与其他函数相同,也可完成如赋值、条件测试、循环、函数调用等功能。构造函数既可在类声明之中定义,也可在类声明之外定义。
例3-22
本例中,我们将默认构造函数定义为Inline类型,将带参构造函数的定义放到类声明之外。