哈哈哈乌龟越狱了
目录
浅拷贝:简单的赋值拷贝炒作
深拷贝:在堆区重新申请空间进行拷贝操作
浅拷贝带来的问题就是堆区的内存重复释放;深拷贝是?拷贝的时候重新申请一块内存,记录的数据是一样的,指向的内存是不一样的?
20240411,内存分区模型,new-delete语句-CSDN博客(一些根本不复习学了就忘还找不到笔记人士,乐,还好学的不多?/不是)
如果属性在堆区开辟的,一定要自己构造深拷贝函数避免出现问题
- #include<iostream>
- using namespace std;
- class Person
- {
- public:
- int m_age;
- int* m_height;//指针接收
- Person()
- {
- cout << "Persong 默认构造 函数的调用" << endl;
- }
- Person(int age,int height)
- {
- m_age = age;
- m_height=new int(height);//把身高创建在堆区,new返回的是该数据类型的指针
- cout << "Persong 有参构造 函数的调用" << endl;
- }
- //系统提供的拷贝函数是浅拷贝
- //自己写一个深拷贝构造函数,解决深拷贝带来的问题
- Person(const Person &p)
- {
- m_age = p.m_age;
- //m_height = p.m_height;编译器写的
- m_height = new int(*p.m_height);
- //在堆区申请一块区域,记录*p_height的内容,即,在堆区创建数据*p_hright
- //此时new int(height)没有释放
- cout << "Persong 拷贝构造 函数的调用" << endl;
- }
- ~Person()
- {
- if (m_height != NULL)
- {
- delete m_height;//释放
- m_height = NULL;//初始化
- }
- cout << "Persong 默认析构 函数的调用" << endl;//将堆区开辟的数据做释放操作
- }
- };
- void test01()
- {
- Person p1(28,180);//执行了一次析构函数,指针指向的内存已经被释放掉了
- cout << "p1的年龄为" << p1.m_age <<"身高为"<<*p1.m_height << endl;
- Person p2(p1);
- //拷贝了m_height记录的地址,此时m_height不为空,
- //但是地址指向的地方已经被释放了,再进行一次释放,非法操作
- cout << "p2的年龄为" << p2.m_age << "身高为" << *p2.m_height << endl;
- //函数结束一起释放
- }
- int main()
- {
- test01();
- system("pause");
- return 0;
- }
构造函数():属性1(值 1),属性2(值2)···{ }
构造函数(int a ,int b ,```):属性1(a),属性2(b)···{ }
- #include<iostream>
- using namespace std;
- class Person
- {
- public:
- int m_a;
- int m_b;
- int m_c;
- Person () :m_a(10), m_b(20), m_c(30) {}//不能修改数值
- Person(int a, int b, int c) :m_a(a),m_b(b),m_c(c){}//可以修改
- };
- void test01()
- {
- Person p;
- Person p1(540, 23, 45);//int a=540,m_a(a)
- cout << p.m_a << "\t" << p.m_b << "\t" << p.m_c << endl;
- cout << p1.m_a << "\t" << p1.m_b << "\t" << p1.m_c << endl;
- }
- int main()
- {
- test01();
- system("pause");
- return 0;
- }
俺的BUG:没有特意创建一个子对象,无法输出被嵌套的子对象
构造和析构的顺序相反
- #include<iostream>
- #include<string>
- using namespace std;
- class Phone
- {
- public:
- string m_Pname;
- Phone(string Pname)
- {
- m_Pname = Pname;
- cout << "Phone的 构造函数 调用" << endl;
- }
- ~Phone()
- {
- cout << "Phone的 析构函数 调用" << endl;
- }
- };
- class Person
- {
- public:
- string m_Name;
- Phone m_Phone;
- Person(string name, string phone) :m_Name(name), m_Phone(phone)
- {
- cout << "Person的 构造函数 调用" << endl;
- }
- ~Person()
- {
- cout << "Person的 析构函数 调用" << endl;
- }//先释放PERSON的,再释放PHONE的
- };
- void test01()
- {
- Person p("张三", "华为p60");
- cout << p.m_Name << endl;//先构造了一个Phone类,先调用了PHONE的构造函数,再PERSON的构造函数
- //cout << p.m_Name << "拿了" << p.m_Phone << endl;//编译错误
- //说没有 操作数 能匹配<<的运算符
- }
- int main()
- {
- test01();
- system("pause");
- return 0;
- }
静态成员变量:所有对象共享同一份数据,编译阶段分配内存,类内声明,类外初始化
静态成员函数:所有对象共享同一个函数,静态成员函数只能访问静态成员变量
- #include<iostream>
- #include<string>
- using namespace std;
-
- class Person
- {
- public:
- //(全局?共享),编译分配,类内声明&类外初始化(否则无法访问)
- static int m_a;
- int m_c;
- static void func()
- {
- m_a = 999;
- //m_c = 888;//静态成员函数只能访问静态成员变量 因为所有对象共享,无法区分m_c属于哪一个对象?
- cout << "静态成员函数 func() 的调用" << endl;
- }
- private:
- //静态成员变量,函数 也有访问权限
- static int m_b;
- static void func2()
- {
- cout << "private 静态成员函数 func() 的调用" << endl;
- }
- };
- //类外初始化,初始化了之后,没有修改的情况下,就是100
- int Person::m_a = 100;
- int Person::m_b = 300;
-
- void test01()
- {
- Person p;
- cout << p.m_a << endl;//无法解析的外部符号
- Person p2;
- cout << p2.m_a << endl;//通过对象访问
- p2.m_a = 200;
- cout << p2.m_a << endl;
- cout << p.m_a << endl;//输出200,P和P1共享这一个静态变量
- }
- void test02()
- {
- //静态成员变量,不属于某个对象上,所有对象共享同一份数据
- //两种访问方式:通过对象,通过类名
- cout << Person::m_a << endl;
- //cout << Person::m_b << endl;//m_b是私有作用域,不能类外访问
- }
- void test03()
- {
- //静态成员函数访问:对象,类名
- Person::func();
- Person p,p1;
- p.func();
- p1.func();
- //Person::func2();无权限
- }
- int main()
- {
- test02();//输出100
- cout << endl;
- test01();
- cout << endl;
- test02();//输出200,
- cout << endl;
- test03();
- test02();
- system("pause");
- return 0;
- }
只有非静态的变量才在对象上
- #include<iostream>
- #include<string>
- using namespace std;
-
- class Person
- {
-
- };
- class Pers
- {
- int m_a;
- int m_b;
- static int m_c;//不属于类的对象上
- void func(){}//也
- static void func2(){}//也
- };
- int Pers::m_c = 800;
- void test01()
- {
- Person p;
- cout << "size of Person p=" << sizeof(p) << endl;
- //空对象占用内存 1
- //C++编译器会给每个空对象也分配一个字节空间,是为了区分空对象占内存的位置
- //(区分不同的空对象)每个空对象也应该有一个独一无二的内存地址
- }
- void test02()
- {
- Pers p;
- cout << "size of Pers p=\t" << sizeof(p) << endl;//内存对齐成员变量
- }
- int main()
- {
- test01();
- test02();
- system("pause");
- return 0;
- }
每一个非静态成员函数只会诞生一份函数实例,也就是多个同类型的对象会公用一块代码,this指针指向被调用的成员函数所属的对象
THIS指针是隐含每一个非静态成员函数内的一种指针,不需要定义,直接使用
用途:当形参和成员变量同名时,可以用THIS指针来区分;在类的非静态成员函数中返回对象本身,可以使用 RETURN *THIS
- #include<iostream>
- #include<string>
- using namespace std;
- //解决名称冲突
- class Person
- {
- public:
- int age;
- Person(int age)
- {
- //age = age;//编译器认为三个age是同一个,没有和成员变量区分开
- this->age = age;//this指针指向被调用的成员函数所属的对象
- }
- void Personaddage(Person& p)
- {
- this->age += p.age;//两个变量的AGE相加 || 一个变量的AGE累加
- }
- //用引用来接收
- Person& Personaddage1(Person& p)
- {
- this->age += p.age;//两个变量的AGE相加 || 一个变量的AGE累加
- return *this;//返回对象本身
- }
- Person Personaddage2(Person& p)
- {//返回值
- this->age += p.age;
- return *this;
- }
- };
-
- void test01()
- {
- Person p1(18);
- cout << "p1的年龄是 " << p1.age << endl;
- }
- void test02()
- {
- Person p(80);
- p.Personaddage(p);
- cout << "p的年龄是 " << p.age << endl;
- Person p1(2);
- p.Personaddage(p1);
- cout << "p的年龄是 " << p.age << endl;
- //p.Personaddage(p1).Personaddage(p1).Personaddage(p1).Personaddage(p1);
- //超级连加,错误,第一次函数运算完成,返回一个VOID
- p.Personaddage1(p1).Personaddage1(p1).Personaddage1(p1).Personaddage1(p1);//链式编程思想
- cout << "p的年龄是 " << p.age << endl;
- p.Personaddage2(p1).Personaddage2(p1).Personaddage2(p1).Personaddage2(p1);//链式编程思想
- //只运算了第一次,值返回就是?复制一份?和本体值相同,但是不是本体了
- cout << "p的年龄是 " << p.age << endl;
- }
- int main()
- {
- test01();
- test02();
- system("pause");
- return 0;
- }
C++中空指针也是可以调用成员函数,但是也要注意有么有用到THIS指针
如果用到,需要加以判断保证代码的健壮性?
- #include<iostream>
- #include<string>
- using namespace std;
- //解决名称冲突
- class Person
- {
- public:
- int m_age;
- void showPersonName()
- {
- cout << "this is Person Class" << endl;
- }
- void showPersonAge()
- {
- if (this == NULL)
- {
- return;//不会走到下一步
- }
- cout << "m_age=" << m_age << endl;
- //cout << "m_age=" << this->m_age << endl;但是this现在是一个空指针,
- }
- };
-
- void test01()
- {
- Person* p = NULL;
- p->showPersonName();
- //p->showPersonAge();//报错
- }
-
- int main()
- {
- test01();
- system("pause");
- return 0;
- }
成员函数后加CONST后-》常函数;常函数不可以修改成员属性,成员属性声明时加关键字MUTABLE后,常函数中依然可修改
在成员函数后加CONST,本质上修饰的时THIS指针,让指针指向的值也不可修改
常对象:声明对象前加CONST,常对象只能调用常函数
- #include<iostream>
- #include<string>
- using namespace std;
- //解决名称冲突
- class Person
- {
- public:
- int m_age;//不能直接设置一个初始值,反而会报错受用未初始化的内存p
- mutable int m_b;//特殊变量,常函数中也可以修改
- void showage()const//(const) Person *const this
- //在成员函数后加CONST,本质上修饰的时THIS指针,让指针指向的值也不可修改
- {
- //m_age = 100;不可修改
- //this->m_age = 100;
- //this 指针的本质,指针常量,指针的指向不可修改,Person *const this
- //this = NULL;不可修改
- cout << "m_age=" << m_age << endl;
- m_b = 232;
- cout << "m_b=" << m_b << endl;//特殊变量可以修改
- }
- void func(){}
- };
- void test01()
- {
- Person p;
- p.showage();
- }
- void test02()
- {
- const Person p;//常对象
- //p.m_age = 1000;//不可修改
- p.m_b = 454;//可以修改
- p.showage();//常对象只能调用常函数
- //p.func();//不可以调用普通成员函数,因为普通成员函数可以修改属性
- }
- int main()
- {
- test01();
- system("pause");
- return 0;
- }