目录

1、类成员的就地初始化example

class S { 
int m = 7; // ok, copy-initializes m
int n(7); // 错误:不允许用小括号初始化
std::string s{'a', 'b', 'c'}; // ok, direct list-initializes s
std::string t{"Constructor run"}; // ok
int a[] = {1,2,3}; // 错误:数组类型成员不能自动推断大小
int b[3] = {1,2,3}; // ok
// 引用类型的成员有一些额外限制,参考标准
public:
S() { }
};

2、构造函数初始化

【C++grammar】C++类数据成员的初始化_ide
【C++grammar】C++类数据成员的初始化_ide_02

A data field is an object type (Object in Object / Embedded Object) (类的数据域是一个对象类型,被称为对象中的对象,或者内嵌对象)
The embedded object must be constructed before the body of ctor is executed (内嵌对象必须在被嵌对象的构造函数体执行前就构造完成)

class Time { /* Code omitted */ }
class Action {
public:
Action(int hour, int minute, int second) {
time = Time(hour, minute, second); //time对象应该在构造函数体之前构造完成
}
private:
Time time;
};
Action a(11, 59, 30);

解释time是Time的对象,是Action的内嵌对象
需要注意的地方:
在构造函数的函数体中,不可以初始化类的数据成员
构造函数的函数体执行之前,类中的数据成员必须完成初始化

3、默认构造函数:Default Constructor

默认构造函数是可以无参调用的构造函数,既可以是定义为空参数列表的构造函数,也可以是所有参数都有默认参数值的构造函数

class Circle1 {
public:
Circle1() { // 无参数
radius = 1.0; /*函数体可为空*/
}
private:
double radius;
};
class Circle2 {
public:
Circle2(double r = 1.0) // 所有参数都有默认值
: radius{ r } {
}
private:
double radius;
};

【C++grammar】C++类数据成员的初始化_c++_03

4、举例

class Circle {
private:
double radius;
public:
double getArea() {
return 3.14 * radius * radius;
}
};
class Square {
private:
double side;
public:
double getArea() {
return side * side;
}
};
class Combo {
private:
Circle c;
Square s;

};

int main()
{
Combo o{};
cout<<o.c.getArea() << endl;
return 0;
}

此时,c对象是个私有的,所以不能直接访问
【C++grammar】C++类数据成员的初始化_类_04
有关代码:

class Circle {
private:
double radius;
public:
//指示编译器生成无参构造函数
Circle() = default;
//构造函数
Circle(double r) {
radius = r;
}
double getArea() {
return 3.14 * radius * radius;
}
};
class Square {
private:
double side;
public:
//指示编译器不构造默认构造函数
//Square() = delete;
// 私有数据成员side double side
Square(double side) :side{ side } {}
//或者写成
/*
Square(double side)
{
this->side = side;
}
*/
double getArea() {
return side * side;
}
};
class Combo {
public:
Circle c;
Square s;
//构造函数.内嵌对象的构造必须在构造函数体之前就完成了
Combo() :s{1.0} {}
};

int main()
{
Combo o{};
cout<<o.c.getArea() << endl;
return 0;
}

【C++grammar】C++类数据成员的初始化_ide_05

5、成员的初始化方法的优先级

【C++grammar】C++类数据成员的初始化_ide_06
一个成员同时有就地初始化和构造函数列表初始化,则就地初始化语句被忽略不执行