C++类实例的构造是程序中经常用到的,因此对此需要有基本的了解,才能避免低级错误。
初始化是指成员变量的初始化,发生在构造函数之前(或者说是先于构造函数中的语句执行),初始化的过程是一定存在的,是对象/简单类型变量分配内存空间的同时进行的;构造函数是分配内存空间之后选择进行的。
构造函数本质上和普通函数是一样的,与普通函数的区别主要3点:
- 通过new操作符构建对象时会“自动”调用;
- 构造函数无返回值;
- 不能像其他成员函数一样由实例显式调用。
#pragma once
class person
{
public:
person(int i)
:year(i)
, age(year)
{
// 初始化列表的内容优先于构造函数的
// 初始化列表不是函数调用,变量的初始化顺序是根据声明的顺序进行的(这里age先初始化然后year在初始化)
}
int getAge() { return age; }
int getYear() { return year; }
private:
int age;
int year;
};
类中的2个成员变量进行了初始化,启动year成员通过构造函数参数i进行初始化,age通过year进行初始化。
这段代码的问题在于,age无法按“预期”正常的执行,原因如下:
初始化不同于函数,year和age的初始化不是按照构造函数中初始化列表的顺序一个一个进行初始化,而是按照变量在类中声明的先后顺序进行初始化。
本例是先初始化age,再初始化year,问题就在此,age使用了未初始化的year是一个无法预测的值;year是正常的初始化。
测试与结果:
person p1(100);
std::cout << "Age= " << p1.getAge() << " Year = " << p1.getYear() << std::endl;
// Age= -858993460 Year = 100
附备忘知识点:
类成员变量中引用变量、常量只能通过初始化列表进行初始化。
常量不初始化报错如下图
正确的初始化:
#pragma once
class person
{
public:
person(int& i)
:year(i)
, age(year)
, outValue(i)
, conValue(i)
{
// 初始化列表的内容优先于构造函数的
// 初始化列表不是函数调用,变量的初始化顺序是根据声明的顺序进行的(这里age先初始化然后year在初始化)
// conValue = 1; // 错误,表达式左值必须是可修改的左值
}
int getAge() { return age; }
int getYear() { return year; }
int getOutValue() { return outValue; }
int getConstValue() { return conValue; }
private:
int age;
int year;
int &outValue;
const int conValue;
};