目录
2. 成员变量在类中声明次序就是其在初始化列表中的初始化顺序,与其在初始化列表中的先后次序无关。
一、初始化列表
初始化列表:以一个
冒号开始
,接着是一个以
逗号分隔的数据成员列表
,每个
"
成员变量
"
后面跟一个
放在括
号中的初始值或表达式。
class position
{
public:
void print()
{
cout << _compus << " " << _building << " " << _dormitory << endl;
}
position(int compus =1, int building=2, int dormitory=301)
: _compus(compus)
,_building(building)
, _dormitory(dormitory)
{}
private:
int _compus;
int _building;
int _dormitory;
};
注意:
使用构造函数之后,对象的成员已经有了一个初始值,但不能叫做类对象成员初始化,构造函数体中的语句只能将其称作为赋初值,因为初始化只能初始化一次,但构造函数体内可以多次赋值。
而类变量成员在初始化列表只有出现一次,初始化一次。
1、类中包含以下成员,必须放在初始化列表位置进行初始化:
1.1、引用成员变量
1.2、const成员变量
1.3、自定义类型成员变量(前提是这个类没有默认构造函数)
int& a;
const int b;
A c;
2. 成员变量在类中声明次序就是其在初始化列表中的初始化顺序,与其在初始化列表中的先后次序无关。
class A
{
public:
A(int a)
:_a1(a)
,_a2(_a1)
{}
void Print()
{
cout<<_a1<<" "<<_a2<<endl;
}
private:
int _a2;
int _a1;
};
int main()
{
A xx(1);
xx.Print();
}
输出的值是多少?还是编译错误?
声明次序就是其在初始化列表中的初始化顺序
_a2先声明的,_a1其次。
所以初始化先初始化_a2,给_a2初始化的值是_a1,_a1此时没有初始化是随机值,所以_a2是初始值。_a1再初始化,将a(1)赋给_a1。
3.隐式转换 和 explicit关键字
class position
{
public:
void print()
{
cout << _dormitory << endl;
}
position(int dormitory = 301)
: _dormitory(dormitory)
{}
private:
int _compus;
int _building;
int _dormitory;
};
int main()
{
position p1(202);
position p2 = 303;
p1.print();
}
这里的position p2 = 303;;
实际上是两步:
先拷贝构造,然后再去调用默认构造函数。编译器会优化把两步优化为一步,叫隐式转换 。
但
explicit position(int dormitory = 301)
: _dormitory(dormitory)
{}
构造函数之前加explicit,编译器将会禁止单参构造函数的隐式转换。
二、 static
声明为
static
的类成员
称为
类的静态成员
,用
static
修饰的
成员变量
,称之为
静态成员变量
;用
static
修饰
的
成员函数
,称之为
静态成员函数
。
class position
{
public:
private:
static int _aa;
static int _bb;
};
记住:
静态成员变量必须在类外定义,定义时不添加static关键字
int position:: _aa = 0;
int position:: _bb = 1;
特性:
1、静态成员为所有类对象共享,存在于静态区,不属于某个具体的实例。
2. 静态成员变量必须在类外定义,定义时不添加static关键字
3.
类静态成员即可用类名
::
静态成员或者对象
.
静态成员来访问
4.
静态成员函数
没有
隐藏的
this
指针
,不能访问任何非静态成员
class A {
public:
private:
int a = 10;
B b = 20;
int* p = (int*)malloc(4);
static int n;
} ;
非静态成员变量,可以在成员声明时给缺省值。
这里不是初始化,这里是给声明的成员变
量缺省值
。
感谢观看。