初始化成员
构造函数的一个重要任务就是给成员初始化,初始化成员有两种办法,一种是手动给成员赋值,另一种是使用初始化列表。这里介绍第二种,格式为:
类名::构造函数名(参数表): (成员初始化表){ 构造函数体 }
构造函数中的初始化列表只需要在参数列表的后面加一个冒号(:
),然后将要初始化的成员按照成员名(参数)
的格式排列在后面,个成员之间用逗号隔开。
例如:
class Test
{
public:
int A;
int B;
Test(int a);
};
Test::Test(int a)
:A(a),B(10) //给成员变量 A、B 初始化,不一定要和参数列表写在一行
{ /* …… */ }
其中成员的初始化顺序不是按照初始化列表中的顺序来的,而是按照成员声明的顺序来的,例如:
/* Test类的声明同上 */
Test::Test(int a)
:B(10),A(a) // 虽然 B 在前面,但还是 A 先初始化
{/* …… */}
Test::Test(int a)
:B(a),A(B) //此处 A 的初始化依赖了 B,然而是 A 先初始化,这就导致 A 得到了 B 中还没初始化的错误内容
{/* …… */}
构造函数与析构函数的调用
构造函数不能直接调用,只能通过声明一个对象或者使用new 运算符动态创建对象时由系统自动调用。
例如:
class Test
{
public:
int A;
Test();
Test(int a);
};
/* 此处省略定义构造函数部分 */
int main()
{
Test t; // 调用无参构造函数
Test t2(10); // 调用带参构造函数
Test t3 = Test(10); // 同上
Test *t = new Test; // 动态创建对象,调用无参构造函数
Test *t2 = new Test(10); // 动态创建对象,调用带参构造函数
}
而析构函数则不同,它能够通过对象主动调用,并在以下两种情况下它会自动调用:
-
若一个对象被定义在一个函数体内,当这个函数结束时(声明的变量的生命周期结束)会自动调用。
-
若一个对象是使用 new 运算符动态创建,在使用 delete 释放时会自动调用。
例如:
/* Test类的声明接上 */
Test::~Test() // 修改一下析构函数,让它打印一条消息
{
cout << "Test的析构函数被调用" << endl;
}
int main()
{
cout << "p1" << endl;
{
Test t1(1); // t1 的生命周期就只在这个大括号内
} //因此在这个位置 t1 的析构函数就会被调用
cout << "p2" << endl;
Test *t2 = new Test(10);
delete t2; // t2 所指对象的析构函数在此被调用
cout<<"p3"<<endl;
{
Test *t3 = new Test;
} // t3 所指对象的析构函数并不会被调用,因为没有使用 delete 运算符
}
输出结果为:
p1
Test的析构函数被调用
p2
Test的析构函数被调用
p3
上述代码中 t1 对象的析构函数调用的位置有点微妙,它是在代码离开大括号}
的那瞬间的位置被调用的,因为一个变量只在直接包含它的那层大括号的范围内存活
结构的初始化及使用
结构变量的初始化和数组变量的初始化一样,采用花括号括起来的初始值列表的形式。
例如:
rationalNumber x={12,46};
该语句中,其初始化值按序赋值给各个成员,即12和46分别赋值给了 x 的 fenzi 和 fenmu 成员。
结构变量的使用有两种方式:一种是把结构变量当做一个整体使用;另一种是拆开了用,单独操作其中的某个成员:
- 当结构变量当做一个整体使用时,有两个运算符:赋值运算符 = 和地址运算符 & 可以直接作用于结构变量上;
例如:
rationalNumber x = {12,46}, y ;
y = x ; // 结构变量中的每个成员分别赋值
rationalNumber *p = &x; // 声明结构指针,并初始化为 x 的地址
- 当结构变量拆开使用时,需要访问结构变量的成员,并可以像使用普通变量那样来使用结构变量的成员,如分数的两个成员就可以看成普通的 int 类型变量。
其中:拆开结构的方式有两种,一种是使用结构名 + 圆点运算符(.
);另一种是使用指向结构变量的指针 + 箭头运算符(->
)。
例如:
rationalNumber x= {12,46}, y ;
y = x ; // 结构变量中的每个成员分别赋值
rationalNumber *p = &x; // 声明结构指针 p,并让 p 指向 x
x.fenzi = 18; // 使用圆点操作符访问并修改 x 的成员 fenzi
p->fenmu = 108; // 使用箭头操作符并修改 x 的成员 fenmu