拷贝构造函数
Person(const Person & P)
Person P1(P2)或Person P1=Person (P2)
不能用拷贝构造函数初始化匿名对象
若Person(P1)等价于Person P1;写到右值可以做拷贝构造函数
拷贝构造函数调用时机
- 用已经创建好的对象来初始化新的对象
- 以值传递的方式给函数参数传值
- 以值得方式返回局部对象
构造函数的调用规则
- 若自己提供了有参构造函数,那么系统不会提供默认构造函数;但还会提供拷贝构造函数,进行简单的值拷贝,系统默认给一个类提供默认构造、拷贝构造、析构函数
- 当提供了拷贝构造,那系统不会提供其他构造
深拷贝和浅拷贝
浅拷贝
由系统做的简单的值拷贝,会释放堆区空间
如属性里有指向堆区空间的数据,那么简单的浅拷贝会导致重复释放内存异常
解决:自己提供拷贝构造函数进行深拷贝
初始化列表基本使用:
要有参构造初始化数据
利用初始化列表来初始化数据:构造函数后+ :属性(参数),属性(参数)
Explicit关键字作用
(隐式类型转换)Mystring str =Mystring(10)
Explicit关键字防止隐式类型转换
New运算符的使用:(不使用malloc)
所以new出来的对象都会返回类型的指针malloc韩慧void还要强转
Malloc不会调用构造,但new会调用
New是运算符;malloc是函数
New会返回一个该类型的指针,会释放堆区空间
Ddelet也是运算符,配合new使用,malloc配合free使用
用void*接受new出来的指针,会出现堆区释放的问题
通过new开辟数组一定会调用默认构造函数
Person PArray2【2】={person (1),person(2)} ;在栈区上开辟数组,可以指定有参构造
Delete【】pArray;释放数组
静态成员变量和静态成员函数:
静态成员变量
静态关键字:static
- 编译阶段分配内存,所有对象共享数据;
- 通过对象访问属性,通过类名访问属性
- 有权限控制
静态成员变量必须在类中声明,在类外定义
静态数据成员不属于某个对象,在为对象分配空间中不包括静态成员所占空间
静态数据成员可以通过类名或者对象来引用
静态成员函数:
不可以访问普通成员,会共享数据
可以通过对象访问,也可以通过类名访问
非成员静态变量,属于对象身上;非静态成员函数,不属于对象身上;静态成员变量,不属于对象身上
单例模式案例:主席
- 目的为了类中只有一个实例,实例不需要自己释放
- 将默认构和拷贝构造私有化
- 内部维护一个对象构造
- 私有化唯一指针
- 对外提供getinstance方法来访问这个指针
- 保证类中只能实例化唯一一个对象
class ChairMan
{
private:
ChairMan()
{
}
ChairMan(const ChairMan&c)
{}
public:
static ChairMan* getInstance()
{
return singleMan;
}
private:
static ChairMan * singleMan;
};
ChairMan * ChairMan::singleMan = new ChairMan;
void test01()
{
ChairMan * cm1 = ChairMan::getInstance();
ChairMan * cm2 = ChairMan::getInstance();
if (cm1 == cm2)
{
cout << "cm1 与 cm2相同" << endl;
}
else
{
cout << "cm1 与 cm2不相同" << endl;
}
}
int main(){
test01();
system("pause");
return EXIT_SUCCESS;
}
打印机案例:对比主席案例,提供了打印功能,和统计打印次数功能
class Printer
{
private:
Printer(){ m_Count = 0; };
Printer(const Printer& p);
public:
static Printer* getInstance()
{
return singlePrinter;
}
void printText(string text)
{
cout << text << endl;
m_Count++;
cout << "打印机使用了次数为: " << m_Count << endl;
}
private:
static Printer* singlePrinter;
int m_Count;
};
Printer* Printer::singlePrinter = new Printer;
void test01()
{
Printer * printer = Printer::getInstance();
printer->printText("离职报告");
printer->printText("入职报告");
printer->printText("加薪申请");
printer->printText("升级申请");
printer->printText("退休申请");
}
int main(){
test01();
system("pause");
return 0;
}
对象模型:
成员变量和成员属性分开处理,内部会区分
空类大小为1.每一个实例的对象都有独一无二的地址,char维护这个地址
This指针的基本使用
解决一个非内联成员函数只诞生一份实例,即为对象共用一块代码
This指针指向被调用的成员函数所属的对象
This隐含与每个类的非静态成员函数中。只有非静态成员函数才有this指针
This可以解决命名冲突,*this指向对象本体
空指针访问成员函数
如果成员函数没有用到this ,那么可以空指针直接访问;如果成员函数用到了this指针,可以加if判断,如果this为NULL会return
常函数 常对象
常函数: void func() const{};修饰的是this指针 const type * const this
常函数不能修改指针执行的值,在对象前加入const修饰 const Person p1;
常对象不能调用普通的成员函数,可以调用常函数
用mutable修饰的关键字是在常函数可以修改的
欢迎关注技术公众号,获取更多软件学习干货!
我们能为你提供什么?
技术辅导:C++、Java、嵌入式软件/硬件
项目辅导:软件/硬件项目、大厂实训项目
就业辅导:就业全流程辅导、技术创业支持
对接企业HR:培养输送优质性人才