一、深拷贝与浅拷贝
1、深拷贝:拷贝的时候先开辟出和源对象大小一样的内存空间,然后将源对象里的内容拷贝到目标对象中,这样两个指针就指向了不同的内存地址,但是里面的内容是一样的。这样不但达到了我们想要的目的,还不会出问题。两个指针先后去调用析构函数,分别释放自己所指向的位置。即每次增加一个指针就意味着申请一块新的内存,并让这个指针指向新的内存,深拷贝的情况下不会出现重新释放同一块内存的错误。
2、浅拷贝:又称值拷贝,将 源对象的值拷贝到目标对象中去,本质上说源对象和目标对象共用一块实体,只是所引用的变量名不一样,但还是同样的地址。
3、深拷贝的实现:深拷贝的拷贝构造函数和赋值运算符的重载
Person(const char *name)
{
m_Name = new char[strlen(name)+1];//先开辟出和源对象一样大的内存区域
strcpy(m_Name,name);//然后将需要拷贝的数据赋值到目标拷贝对象中
}
~Person()
{
if(m_Name != NULL)
{
delete[] m_Name;//不会出现重复释放同一块内存的错误
m_Name = NULL;
}
}
二、类对象作为类成员
当其他类对象作为本类中的成员:
构造的顺序:先调用其他类的构造函数,再调用本类的构造函数;
析构的顺序:和构造的顺序正好相反。
#include <iostream>
using namespace std;
class Phone{
public:
string m_phone;
Phone(){}
~Phone(){}
};
class Game{
public:
string m_game;
Game(){}
~Game(){}
};
class Person{
public:
string m_person;
Game m_game;//用类对象来定义变量
Phone m_phone;//用类对象来定义变量
Person(string name,string pname,string gname){
cout<<"姓名:"<<name<<endl;
cout<<"手机:"<<pname<<endl;
cout<<"游戏:"<<gname<<endl;
}
~Person(){}
};
int main()
{
Person p("xz","iphone","wary");
return 0;
}
三、静态成员
在类定义中,他的成员(成员变量和成员方法),这些成员都可以用关键字static进行声明
特点:不管这个类创建了多少个对象,静态成员只有一个拷贝。这个拷贝被所有属于这个类的对象所共享。
静态成员变量:
1、必须在类中声明,在类外定义;
2、静态成员变量不属于某个对象,而是属于类,所有对象共享;
3、静态成员变量可以通过类名或者对象名来获取。
静态成员函数:
1、静态的成员函数只能访问静态的成员变量;
2、普通的成员函数可以访问静态的或者非静态的成员变量、成员函数;
3、可以通过类名或者对象名来访问。
class Person{
public:
int m_A;//普通的成员变量
static int m_B;//静态的成员变量
static void fun()//静态成员函数
{
m_B = 200;
cout<<"静态成员函数被调用了"<<endl;
}
void fun1()
{
m_A=100;
m_B=200;
}
};
int Person::m_B = 100;//静态成员变量在类外定义
int main()
{
Person p1;
cout<<"p1.m_B="<<p1.m_B<<endl;//输出在类外修改后的值
Person p2;
p2.m_B=450;
cout<<"p2.m_B="<<p2.m_B<<endl;//输出450
return 0;
}
四、this指针
this指针指向用来调用 成员函数的对象,谁调用方法,this就指向谁;
this被作为隐式参数传递给方法,每一个非静态的的成员方法都是用this指针;
作用:
1、当形参和成员变量同名时,可以使用this指针来区分
class Person{
public:
string name;
int age;
Person(string name, int age) {
this->name = name;
this->age = age;
}
};
2、在类的非静态成员方法中返回对象本身,可以使用return *this
Person& getOlder(Person& p) {
if (age > p.age) {
return *this;
}
}