C++黑马程序员——P112-114. 类对象作为类成员; 静态成员; 成员变量和成员函数分开存储
- P112. 类和对象——对象特性——类对象作为类成员
- P113. 类和对象——静态成员
- P114. 类和对象——对象特性——成员变量和成员函数分开存储
- P112
C++类中的成员可以是另一个类的对象,我们称该成员为 对象成员
1 class A{};
2 class B
3 {
4 A a;
5 };
B类中有对象a作为成员,a为对象成员
那么当创建B对象时,A与B的构造和析构顺序是谁先谁后呢?
1 #include <iostream>
2 #include <string>
3 using namespace std;
4
5 class Phone
6 {
7 public:
8 //构造函数
9 Phone(string brand)
10 {
11 cout << "Phone的构造函数调用" << endl;
12 m_Brand = brand;
13 }
14 //析构
15 ~Phone()
16 {
17 cout << "Phone的析构函数调用" << endl;
18 }
19 //品牌名称
20 string m_Brand;
21 };
22
23 class Person
24 {
25 public:
26 //构造函数
27 //初始化列表可以告诉编译器调用哪一个构造函数
28 Person(string name, string phone):m_Name(name),m_Phone(phone) //后面这个相当于 Phone m_Phone = phone(隐式转换法 调用 构造函数)
29 {
30 cout << "Person的构造函数调用" << endl;
31 }
32 //析构
33 ~Person()
34 {
35 cout << "Person的析构函数调用" << endl;
36 }
37 //姓名
38 string m_Name;
39 //手机
40 Phone m_Phone;
41 };
42
43 void test01()
44 {
45 Person p1("张三", "苹果");
46 cout << p1.m_Name << "拿着" << p1.m_Phone.m_Brand << endl;
47 }
48
49 int main()
50 {
51 test01();
52 return 0;
53 }
运行结果:
结论:
构造:先调用对象成员的构造,再调用本类构造
析构:与构造相反
- P113. 静态成员
静态成员就是在成员变量和成员函数前加上关键字static,称为静态成员
静态成员分为:
- 静态成员变量
1. 所有对象共享同一份数据
2. 在编译阶段分配内存(存放在全局区)
3. 类内声明,类外初始化
- 静态成员函数
1. 所有对象共享同一个函数
2. 静态成员函数只能访问静态成员变量
静态成员变量:
1 #include <iostream>
2 #include <string>
3 using namespace std;
4
5 //静态成员变量
6 class Person
7 {
8 public:
9 //类内声明
10 static int a;
11 };
12
13 //类外初始化
14 int Person::a = 100; //不用在前面写static; 要写类名(Person)和作用域的符号(::)
15
16 void test01()
17 {
18 Person p1;
19 cout << "p1.a = " << p1.a << endl;
20 Person p2;
21 p2.a = 200;
22 cout << "p1.a = " << p1.a << endl;
23 }
24
25 int main()
26 {
27 test01();
28 return 0;
29 }
运行结果:
1 class Person
2 {
3 public:
4 //类内声明
5 static int a;
6 };
7
8 //类外初始化
9 int Person::a = 100; //不用在前面写static; 要写类名(Person)和作用域的符号(::)
10
11 void test02()
12 {
13 //静态成员变量 不属于某个对象上 所有对象都共享同一份数据
14 //因此静态成员变量有两种访问方式:
15 //1. 通过对象进行访问
16 Person p3;
17 cout << "p3.a = " << p3.a << endl;
18 //2. 通过类名进行访问
19 cout << "Person::a = " << Person::a << endl;
20 }
21
22 int main()
23 {
24 test02();
25 return 0;
26 }
运行结果:
静态成员变量也是有访问权限的:
1 class Person
2 {
3 public:
4 //类内声明
5 static int a;
6 private:
7 static int b; //静态成员变量也是有访问权限的
8 };
9
10 //类外初始化
11 int Person::a = 100; //不用在前面写static; 要写类名(Person)和作用域的符号(::)
12 int Person::b = 200; //私有静态成员变量,类外可以声明;但是类外访问不到
静态成员函数:
1 class Person
2 {
3 public:
4 static void func()
5 {
6 cout << "static void func()调用" << endl;
7 }
8 };
9
10 void test01()
11 {
12 //静态成员函数也是两种访问方式
13 //1. 通过对象访问
14 Person p1;
15 p1.func();
16 //2. 通过类名访问
17 Person::func();
18 }
19
20 int main()
21 {
22 test01();
23 return 0;
24 }
运行结果:
静态成员函数 不可以访问 非静态成员变量:
静态成员函数 也是有 访问权限的(和静态成员变量一样):比如在private下定义了一个静态成员函数,那么类外便不能访问这个函数。
- P114. 成员变量和成员函数分开存储
在C++中,类内的成员变量和成员函数分开存储
只有非静态成员变量才属于类的对象上
空对象占用内存空间为:1 字节
1 class Person
2 {
3 };
4
5 void test01()
6 {
7 Person p;
8 //空对象占用内存空间为: 1 字节
9 cout << "size of p = " << sizeof(p) << endl;
10 }
11
12 int main()
13 {
14 test01();
15 return 0;
16 }
运行结果:
为什么每个空对象会占用1个字节:为了区分空对象占内存的位置;每个空对象都应该有一个独一无二的内存地址。
非静态成员变量 属于类的对象上:
1 class Person
2 {
3 int a; //非静态成员变量 属于类的对象上
4 };
5
6 void test02()
7 {
8 Person p;
9 cout << "size of p = " << sizeof(p) << endl;
10 }
11
12 int main()
13 {
14 test02();
15 return 0;
16 }
运行结果:
1 class Person
2 {
3 int a; //非静态成员变量 属于类的对象上
4 static int b; //静态成员变量 不属于类的对象上
5 void func(){} //非静态成员函数 不属于类的对象上
6 static void func2(){} //静态成员函数 不属于类的对象上
7 };
8
9 int Person::b = 0;
10
11 void test02()
12 {
13 Person p;
14 cout << "size of p = " << sizeof(p) << endl;
15 }
16
17 int main()
18 {
19 test02();
20 return 0;
21 }
运行结果:
(〃>_<;〃)(〃>_<;〃)(〃>_<;〃)