对象的特征

对象的一些特性

感觉有用的就

  1. 构造函数和析构函数
  2. this指针

其他都是些细节

 

看构造函数和析构函数怎么写

  1 #include <iostream>
  2 using namespace std;
  3 /*一个对象或者变量没有初始状态,对其使用后果是未知的 
  4 同样的使用完一个对象或变量,没有及时清理,也会造成一定的安全问题
  5  
  6 C++利用构造函数和析构函数,这两个函数将会被编译器
  7 自动调用,完成对象初始化和清理工作。对象的初始化
  8 和清理工作是编译器强制要我们做的事情,因此如果我们
  9 不提供构造和机构,编译器会提供。编译器提供的构造函数
 10 和析构函数是空实现
 11 
 12 构造函数:主要作用在于创建对象时为对象的成员属性赋值,
 13 构造函数由编译器自动调用,无须手动调用
 14 析构函数:主要作用在于对象销毁前系统自动调用,执行一些
 15 清理工作。 
 16  
 17 */
 18 
 19 
 20 /*
 21 构造函数语法:类名(){}
 22 1、构造函数:没有返回值也不写void
 23 2、函数名称与类名相同
 24 3、构造函数可以有参数,因此可以发生重载
 25 4、程序在调用对象时会自动调用构造函数,
 26 无须手动调用,而且只会调用一次 
 27 */
 28 
 29 class Person{
 30 public:
 31     Person(){
 32         cout<<"无参构造函数的调用"<<endl;
 33     }
 34     Person(int a){
 35         age=a;
 36         cout<<"有参构造函数调用"<<endl;
 37     } 
 38     ~Person(){
 39         cout<<"调用析构函数"<<endl; }
 40     //拷贝构造函数
 41     Person (const Person &p){
 42         age=p.age;
 43         cout<<"拷贝构造函数"<<endl; 
 44     }
 45     void setAge(int a){
 46         age=a;
 47     }
 48     int getAge(){
 49         return age;
 50     }
 51 private:
 52     int age;
 53 };
 54  
 55 
 56 /*
 57 析构函数语法:~类名(){}
 58 1、析构函数,没有返回值也不写void
 59 2、函数名称与类名相同,在名称前加上符号~
 60 3、析构函数不可以有参数,因此不可以发生重载
 61 4、程序在对象销毁前会自动调用析构,无须手动调用而且只会调用一次 
 62 */ 
 63 
 64 /*
 65 构造函数的分类及调用
 66 两种分类方法:
 67 按参数分:有参构造和无参构造
 68 按类型分:普通构造和拷贝构造     
 69 
 70 
 71 
 72 三种调用方式:
 73 1、括号法
 74 //Person p1;//默认构造函数调用 
 75 //Person p2(10);//有参构造函数 
 76 //Person p3(p2); //拷贝构造函数 
 77 注意:调用默认构造函数时,不要加() ,编译器会认为是一个函数声明 
 78 2、显示法
 79 //Person p1;
 80 //Person p2 = Person(10);//有参构造
 81 //Person p3 = Person(p2);//拷贝构造  
 82 3、隐式转换法 
 83 Person p4=10;//相当于 Person p4 = Person(10); 
 84 
 85 */
 86 
 87 
 88 /*
 89 拷贝构造函数调用时机
 90 使用一个已经创建完毕的对象来初始化一个新对象
 91 Person p1(10);
 92 Person p2(P1); 
 93 值传递的方式给函数参数传值
 94 void doWork(Person p)
 95 {
 96 
 97 }
 98 void test02()
 99 {
100     Person p;
101     doWork(p);
102 }
103 以值方式返回局部对象 
104 Person doWork2()
105 {
106     Person p1;
107     return p1;
108 }
109 void test03()
110 {
111     Person p = doWork2();
112 }
113 */
114 //值传递的方式给函数参数传值
115 void doWork(Person p)
116 {
117 
118 }
119 void test02()
120 {
121     Person p;
122     doWork(p);
123 }
124 //以值方式返回局部对象 
125 Person doWork2()
126 {
127     Person p1;
128     return p1;
129 }
130 void test03()
131 {
132 //    Person p = doWork2();
133     cout<<doWork2().getAge()<<endl;
134 }
135 void test01()
136 {
137     Person p1;//调用无参构造函数 
138     Person p2(10);//调用有参构造函数 
139     Person p3(p2);
140     cout<<"p2.getAge(): "<<p2.getAge()<<endl;
141     cout<<"p3.getAge(): "<<p3.getAge()<<endl;
142 }
143 
144 
145 
146 /*构造函数调用规则
147 1、默认构造函数(无参,函数体为空)
148 2、默认析构函数(无参,函数体为空) 
149 3、默认拷贝构造函数,对属性进行值拷贝 
150 如果写了拷贝构造函数就不会调用默认的 
151 定义了有参构造函数,C++不再提供默认无参构造,但会提供默认拷贝构造
152 如果定义了拷贝构造函数,C++就不会提供其他构造函数 
153 */
154 //深拷贝与浅拷贝问题
155 /*
156 
157 */ 
158 
159 int main()
160 {
161 //    test01();
162 //    test02();
163     test03();
164     return 0;
165 }
对象的初始化与清理

初始化列表语法,作用同有参构造函数

 1 #include <iostream>
 2 using namespace std;
 3 
 4 
 5 /*
 6 C++提供了初始化列表语法,用来初始化属性
 7 语法:构造函数():属性1(值1),属性2(值2),,, 
 8 */
 9 
10 class Person
11 {
12 public:
13 //    Person(int a,int b,int c){
14 //        m_A=a;
15 //        m_B=b;
16 //        m_C=c; 
17 //    }
18     Person(int a,int b,int c):m_A(a),m_B(b),m_C(c){
19     }
20     int m_A;
21     int m_B;
22     int m_C;
23 };
24 
25 void test01()
26 {
27     Person p(1,2,3);
28     cout<<"p.m_A,B,C "<<p.m_A<<p.m_B<<p.m_C<<endl;
29 }
30 
31 int main()
32 {
33     test01();
34     return 0;
35 }
列表初始化

静态成员变量和静态成员函数

 1 #include <iostream>
 2 using namespace std;
 3 
 4 
 5 //静态成员就是在成员变量和成员函数前加上关键字static,称为静态成员
 6 /*静态成员分为:
 7 -静态成员变量
 8 所有对象共享同一份数据
 9 在编译阶段分配内存
10 类内声明,类外初始化
11 -静态成员函数
12 所有对象共享同一个函数
13 静态成员函数只能访问静态成员变量 
14 */ 
15 
16 class Person{
17 public:
18     //所有对象都共享同一份数据 
19     //编译阶段就分配内存
20     //类内声明,类外初始化操作 
21     static int  m_A;
22     int m_B;
23     static void func(){
24         cout<<"这是静态成员函数"<<endl;
25         cout<<m_A<<endl; //静态函数可以访问静态成员变量 
26 //        cout<<m_B<<endl; 错误的,静态函数不可访问非静态成员变量 
27     }
28 };
29 
30 int Person::m_A=100;
31 
32 void test01(){
33     Person p1;
34     cout<<"p1.m_A="<<p1.m_A<<endl; 
35     Person p2;
36     cout<<"p2.m_A="<<p2.m_A<<endl;
37     p2.m_A=200;
38     cout<<"p2.m_A=200后p1.m_A="<<p1.m_A<<endl;
39     cout<<"p2.m_A="<<p2.m_A<<endl; 
40     
41 }
42 void test02(){
43 
44 //静态成员变量有两种访问方式
45 //1、通过对象进行访问
46 //Person p;
47 //cout<<p.m_A<<endl;
48 //2、通过类名进行访问 
49 cout<<Person::m_A<<endl;
50 
51 }
52 
53 void test03(){
54 //    静态成员函数
55 //通过对象访问 
56     Person p3;
57     p3.func();
58 //    通过类访问
59     Person::func(); 
60 }
61 
62 int main()
63 {
64 //    test01();
65 //    test02();
66     test03();
67     return 0;
68 }
静态成员

看构造和析构调用顺序

 1 #include <iostream>
 2 using namespace std;
 3 
 4 /*C++类中的成员可以是另一个类的对象,我们称该成员为对象成员 
 5 */ 
 6 class Phone{
 7 public:
 8     Phone(string pName){
 9         m_PName=pName;
10         cout<<"Phone创建了"<<endl;
11     }
12     ~Phone(){
13         cout<<"Phone消失了"<<endl;
14     }
15     string m_PName;//手机品牌名称 
16  };
17 
18 class Person
19 {
20 public:
21     Person(string name,string pName):m_Name(name),m_Phone(pName){
22 //        m_Name=name;
23 //        m_PName=pName;
24 cout<<"Person创建了"<<endl;
25     } 
26     ~Person(){
27         cout<<"Person消失了"<<endl;
28     }
29     string m_Name;//姓名 
30     Phone m_Phone;//手机 
31 };
32 
33 void test01()
34 {
35     Person p("张三","苹果");
36 }
37   
38 int main()
39 {
40     test01();
41     return 0;
42 }
类对象做类成员

 对象占多少内存的研究,只有非静态成员变量属于对象

 1 #include <iostream>
 2 using namespace std;
 3 
 4 
 5 /*
 6 在C++中,类内的成员变量和成员函数分开存储
 7 只有非静态成员变量才属于类的对象上 
 8 */
 9 
10 class Person{
11      static int m_A;
12 };
13 class Person1{
14     int m_A;
15     static int m_B;
16     int func(){
17         return m_A;
18     } 
19     static void func2(){
20     }
21 };
22 
23 void test01(){
24     Person p;
25 //    空对象占用内存空间为1
26 //C++编译器会给每个空对象也分配一个字节空间,是为了区分空对象占内存的位置
27 //每个空对象也应该有一个独一无二的内存地址 
28     cout<<"size of p= "<<sizeof(p)<<endl;
29 //    cout<<"id of p = "<<(int)p<<endl; 
30 }
31 void test02(){
32 //    非静态成员变量属于类的对象上
33 //p1有4个字节 
34 //静态成员变量不属于类的对象上 
35     Person1 p1;
36     cout<<"size of p1= "<<sizeof(p1)<<endl;
37 }
38 int main()
39 {
40     test01();
41     test02();
42     return 0;
43 }
成员变量和成员函数分开存储

this指针指向被调用的成员函数的所属对象

 

 1 #include <iostream>
 2 using namespace std;
 3 
 4 /*this指针指向被调用的成员函数所属的对象
 5 this指针是隐含在每一个非静态成员函数内的一种指针
 6 this指针不需要定义,直接使用即可
 7 
 8 this指针的用途:
 9 1、解决名称冲突
10 当形参和成员变量同名时,可用this指针来区分
11 2、返回对象本身用*this
12 在类的非静态成员函数中返回对象本身,可使用return *this 
13 */
14 
15 class Person{
16 public:
17     Person(int age){
18 //        this指针指向被调用的成员函数所属的对象
19         this->age=age;
20         cout<<"age="<<age<<endl; 
21     }
22     int age;
23     
24     Person& PersonAddAge(Person &p)
25     {
26         this->age+=p.age;
27 //this指向p1的指针,而*this指向的就是p1这个对象的本体 
28         return *this; 
29     }
30 };
31 
32 void test01()
33 {
34     Person p(10);
35 }
36 
37 void test02()
38 {
39     Person p1(10);
40     Person p2(10);
41     //链式编程思想 
42     //但我感觉没啥用    p1.PersonAddAge(p2).PersonAddAge(p2).PersonAddAge(p2);
43     cout<<"p1.age="<<p1.age<<endl;
44     cout<<"p2.age="<<p2.age<<endl;
45 }
46 int main()
47 {
48     test01();
49     test02();
50     return 0;
51 }
this指针

 空指针可以调用成员函数

 1 #include <iostream>
 2 using namespace std;
 3 
 4 //C++中空指针也可以调用成员函数的,但是
 5 //也要注意又没有用到this指针
 6 //如果用到this指针,需要加以判断保证代码的
 7 //健壮性 
 8 
 9 class Person{
10     public:
11         void sayHello(){
12             cout<<"HEllo"<<endl;
13         }
14         void showAge(){
15             if(this==NULL)//可以保证代码的健壮性 
16             {
17                 return;
18             }
19             cout<<"m_Age="<<m_Age<<endl;
20         }
21         int m_Age=18;
22 }; 
23 
24 void test01()
25 {
26     Person *p=NULL;
27     p->sayHello();
28     p->showAge();
29 }
30 
31 int main()
32 { 
33     test01();
34     return 0;
35 }
空指针访问成员函数

 

posted @ 2023-09-05 21:35  HuangWQ289  阅读(12)  评论(0编辑  收藏  举报