1. 局部变量初始化
const int SIZE = 5;
int funcStatic() {
static int a1;
static int a2(0); //初始化
static int a3 = 0; //初始化
static int a4(0);
a4 = 0;
cout <<"a1: "<<a1++<<" a2: "<<a2++<<" a3: "<<a3++<<" a4: "<<a4++<<endl;
return 0;
}
int func(){
int b_1(1),b_2 = 2;
char c[] = {'C','+','+'}; // 不含'\0'
char c_1[] = {'C','+','+','\0'};
char c_2[] = "C++"; // 默认追加'\0'
int d_1[SIZE]={1,2},d_2[]={1,2};
cout <<"b_1: "<<b_1<<" b_2: "<<b_2<<endl;
cout <<"sizeof(c) "<<sizeof(c)<<"\nsizeof(c_1) " \
<<sizeof(c_1)<<"\nsieof(c_2) "<<sizeof(c_2)<<endl;
cout <<"sieof(d_1) "<<sizeof(d_1) \
<<"\nsieof(d_2) "<<sizeof(d_2)<<endl;
cout <<"d_1[2] "<<d_1[2]<<endl;
return 0;
}
int main() {
func();
funcStatic();
funcStatic();
return 0;
}
/*
b_1: 1 b_2: 2
sizeof(c) 3
sizeof(c_1) 4
sieof(c_2) 4
sizeof(d) 20
sieof(d_1) 20
sieof(d_2) 8
d_1[2] 0
a1: 0 a2: 0 a3: 0 a4: 0
a1: 1 a2: 1 a3: 1 a4: 0
*/
1.1 静态变量
- 在固定的地址上进行存储分配,在静态数据区(static data area,又 数据段(data segment) )
- 具有局部可见性,内部链接
- 在第一次调用时初始化,且仅初始化一次,作用域外其值保持不变
- 内部类型静态变量,如果未初始化,则编译器默认初始化为0
1.2 常量
- c++中const默认为内部链接;c默认外部连接
- 初始化必须在定义点进行
const int a = 1;
const int d[]={1,2,3,4};
extern const int size = 5; //明确为外部连接
1.3 引用
- 引用被定义时必须初始化
- 引用不可变更
- 没有NULL引用
2. 类成员变量
class Test{
static constexpr int x[3]={1,2,3};
static int s;
const int a[3] = {1,2,3};
const int b = 1;
const int c;
const int d[2];
public:
Test():c(4), d({5,6}) {//warning
cout <<a[0]<<" "<<b<<" "<<c<<" "<<d[0]<<endl;
}
};
int Test::s = 1;
int main() {
Test tl;
return 0;
}
//test.cpp: In constructor ‘Test::Test()’:warning: list-initializer for non-class type must not be parenthesized [enabled by default]
//output
//1 1 4 5
2.1 静态成员
- 在类内定义,类外初始化
2.2 常量成员
- 初始化是在类的构造函数的初始化列表里;
- 构造函数函数体里常量成员已经初始化完毕,不可初始化;
- 特殊的常量数组成员初始化
2.3 静态常量成员
- 在定义的位置初始化
- 特别的静态常量数组成员需要constexpr关键字而非const
constexpr是C++11中新增的关键字,其语义是“常量表达式”,也就是在编译期可求值的表达式。最基础的常量表达式就是字面值或全局变量/函数的地址或sizeof等关键字返回的结果,而其它常量表达式都是由基础表达式通过各种确定的运算得到的。
3. 类对象初始化
class Test{
int a;
public:
Test():a(0){
cout <<"default"<<endl;
}
Test(const int &s):a(s){
cout <<"construct from int"<<endl;
}
Test(const Test &t):a(t.a){
cout <<"copy construction"<<endl;
}
Test& operator=(const Test &t){
a = t.a;
cout <<"operator="<<endl;
return *this;
}
};
int main() {
Test t1; //default
Test t2(2); //construct from int
Test t3(t2); //copy construction
Test t4 = t2; //copy construction
Test t5 = 5; //construct from int
t4 = t5; //operator=
Test t6[2]; //default default
Test t7[2] = {1,2};//construct from int construct from int
return 0;
}
- 类对象的成员利用构造函数列表初始化时,是按定义顺序初始化的
- 通过构造函数初始化.但是对所有类对象,类的静态变量只初始化一次,且数据只有一份.
- 类定义构造函数时必须定义默认构造函数,否则编译出错;默认构造函数,在声明 类的对象 数组或无参数类对象时会被调用;
定义类后编译器默认生成四个成员函数:默认构造函数、析构函数、拷贝构造函数、赋值函数
A(void); // 缺省的无参数构造函数
A(const A &a); // 缺省的拷贝构造函数
~A(void); // 缺省的析构函数
A & operate =(const A &a); // 缺省的赋值函数