wordpress收不到网站,网站建设方案 预算,软件开发公司是干什么的,宁波seo企业网络推广4.2.5 深拷贝与浅拷贝
浅拷贝#xff1a;编译器提供的简单的赋值拷贝操作
深拷贝#xff1a;在堆区重新申请空间#xff0c;进行拷贝操作
示例#xff1a; class Person {
public://无参#xff08;默认#xff09;构造函数Person() {cout 无参构造函数…4.2.5 深拷贝与浅拷贝
浅拷贝编译器提供的简单的赋值拷贝操作
深拷贝在堆区重新申请空间进行拷贝操作
示例 class Person {
public://无参默认构造函数Person() {cout 无参构造函数! endl;}//有参构造函数Person(int age ,int height) {cout 有参构造函数! endl;m_age age;m_height new int(height); //利用关键字new把身高放在堆区返回的是一个地址}//拷贝构造函数 Person(const Person p) {cout 拷贝构造函数! endl;//如果不利用深拷贝在堆区创建新内存会导致浅拷贝带来的重复释放堆区问题//自己写一个拷贝构造函数解决浅拷贝带来的问题在堆区再开辟一段空间m_age p.m_age;//m_height p.m_height 编译器自动提供时的拷贝构造函数写法m_height new int(*p.m_height); //深拷贝重新开辟一块内存//通过传入的地址进行解引用之后再在堆区申请一块内存存入}//析构函数~Person() {
//析构代码将堆区开辟的数据做释放操作堆区的数据需要程序员手动开辟也需要程序员手动释放
//在对象销毁前对堆区的数据释放掉test01执行完了之后所以在析构函数时把数据释放干净cout 析构函数! endl;if (m_height ! NULL) //如果该指针不为空就将其用delete删除{delete m_height;m_height NULL; //防止野指针出现将其置空}}
public:int m_age;int* m_height; //用指针是为了把数据开辟到堆区
};void test01()
{Person p1(18, 180);Person p2(p1); //当我们不提供拷贝构造函数数编译器自动帮我们提供并且做浅拷贝cout p1的年龄 p1.m_age 身高 *p1.m_height endl;cout p2的年龄 p2.m_age 身高 *p2.m_height endl;
}int main() {test01();system(pause);return 0;
} 具体差别如下图所示 总结如果属性有在堆区开辟的一定要自己提供拷贝构造函数防止浅拷贝带来的问题
4.2.6 初始化列表
作用
C提供了初始化列表语法为类中的属性进行初始化类似于构造函数的初始化
语法构造函数()属性1(值1),属性2值2... {}
示例
class Person {
public:传统方式初始化创建对象同时赋值//Person(int a, int b, int c) {// m_A a;// m_B b;// m_C c;//}//初始化列表方式初始化Person(int a, int b, int c) :m_A(a), m_B(b), m_C(c) {}// 写法2Person() :m_A(1), m_B(2), m_C(3) {} 但是值被固定不够灵活void PrintPerson() {cout mA: m_A endl;cout mB: m_B endl;cout mC: m_C endl;}
private:int m_A;int m_B;int m_C;
};int main() {Person p(1, 2, 3);//对应类中的写法2Person p; p.PrintPerson();system(pause);return 0;
} 4.2.7 类对象作为类成员
C类中的成员可以是另一个类的对象我们称该成员为 对象成员
构造函数先构造类中的成员调用类中成员的构造再构造本类
析构函数与构造顺序相反
例如
class A {}
class B
{A a
} 示例
class Phone
{
public:Phone(string name){m_PhoneName name;cout Phone构造 endl;}~Phone(){cout Phone析构 endl;}string m_PhoneName;};class Person
{
public://初始化列表可以告诉编译器调用哪一个构造函数//相当于 Phone m_Phone pName 隐式转换法用pName创建对象Person(string name, string pName) :m_Name(name), m_Phone(pName){ cout Person构造 endl;}~Person(){cout Person析构 endl;}string m_Name;Phone m_Phone;};
void test01()
{//当类中成员是其他类对象时我们称该成员为 对象成员//构造的顺序是 先调用对象成员的构造再调用本类构造//析构顺序与构造相反Person p(张三 , 华为mate60 Pro);cout p.m_Name 使用 p.m_Phone.m_PhoneName 手机! endl;}int main() {test01();system(pause);return 0;
} 4.2.8 静态成员
静态成员就是在成员变量和成员函数前加上关键字static称为静态成员包括静态成员变量和静态成员函数。
静态成员变量静态成员函数特点 所有对象共享同一份数据 不属于任何一个对象上的 在内存中只有一个值其他函数修改之后再调用也会变成修改后的值 程序还没有运行在编译阶段分配内存 类内声明类外初始化必须初始化否则无法使用 也是有访问权限的区别的 所有对象共享同一个函数同静态成员变量 静态成员函数只能访问静态成员变量无法访问非静态成员变量 也有访问权限 调用方式静态成员函数的调用要增加作用域 通过对象进行访问像之前一样正常通过 类名.变量名 进行访问 通过类名进行访问直接用变量的名字进行访问
示例1 静态成员变量
class Person
{public:static int m_A; //静态成员变量类内声明private:static int m_B; //静态成员变量也是有访问权限的
};
int Person::m_A 10; //类外初始化为了说明是Person下的要写作用域Person::
int Person::m_B 10;void test01()
{//静态成员变量两种访问方式//1、通过对象Person p1;p1.m_A 100;cout p1.m_A p1.m_A endl;Person p2;p2.m_A 200; //用p2去修改m_A的值cout p1.m_A p1.m_A endl; //共享同一份数据cout p2.m_A p2.m_A endl;//2、通过类名cout m_A Person::m_A endl;//cout m_B Person::m_B endl; //私有权限访问不到
}int main() {test01();system(pause);return 0;
}
示例2静态成员函数
class Person
{public:static void func() //静态成员函数{cout func调用 endl;m_A 100; //只能访问静态成员变量//m_B 100; //错误不可以访问非静态成员变量//非静态成员变量必须通过创建对象才能够调用当调用静态成员函数程序中只有一份值不知道改变的是哪一个对象上面的非静态成员变量无法区分}static int m_A; //静态成员变量类内声明int m_B; // 非静态成员变量
private://静态成员函数也是有访问权限的static void func2(){cout func2调用 endl;}
};
int Person::m_A 10; //(类外初始化)void test01()
{//静态成员变量两种访问方式//1、通过对象Person p1;p1.func();//2、通过类名Person::func(); //不用对象直接通过类名进行调用但是要写明作用域//Person::func2(); //私有权限访问不到
}int main() {test01();system(pause);return 0;
}