一、this指针
1.1 什么是this 指针
指向当前对象的指针
构造函数中this指向正在被构建的对象首地址
成员函数中 this代表调用这个函数的对象的首地址
1.2 this指针的应用
区分成员变量 和函数参数
this 可以作为函数参数
this 可以作为返回值(实现连续操作)
二、const对象和const函数
const对象就是加了const修饰对象
const A a;
const 函数就是加了const修饰的成员函数
class A{
public:
void show()const{
/*这就是const函数*/
}
void show(){
/*这就是非const函数*/
}
};
1.2 规则
const 函数和非const函数可以构成重载关系
const 对象只能调用const函数
const 函数中只能读成员变量 不能修改成员变量的值 也不能调用非const的成员函数
如果非要在const函数中去修改成员变量 只要在修饰的成员变量上 加一个mutable修饰
非const对象优先调用非const函数,如果没有非const函数则调用const函数。
#include <iostream>
using namespcae std;
class A{
mutable int data;
public:
/*_ZK1A4showEv*/
void show(){
cout << "show()" << endl;
}
/*_ZNK1A4showEv*/
void show()const{
cout << "show()const" << endl;
data=1101;
cout << data << endl;
}
}
int main(){
A var_a;
var_a.show();
const A var_b=var_a;
var_b.show();
}
三、析构函数
3.1析构函数和构造函数同名 在函数名前加~,这个函数是无参的所以一个类型中
只有一个析构函数
3.2作用
可以在一个对象销毁之前 自动调用一次。
用来释放内存 释放资源
3.3 内存相关的两个操作
构造函数 分配内存
析构函数 释放内存
#include <iostream>
using namespcae std;
class A{
int *data;
public:
/*构造函数中分配内存*/
A():data(new int(10)){
/*data= new int(10)*/
cout << "A()" << endl;
}
/*析构函数 负责释放内存*/
~A(){
cout << "~A()" << endl;
delete data;
}
};
int main(){
A *pa = new A[5];//创建5个对象
delete[] pa;
}
四.new delete 比malloc free
new 比malloc多做了一些事
1、如果类型中有类类型的成员 new会自动构建这个成员
2、new 会自动处理类型转换
3、new 会自动调用构造函数
delete 比free多调用了一次析构函数
#include <iostream>
using namespcae std;
struct Date{
int year;
int month;
int day;
Date(){
cout << "Date()" << endl;
}
~Date(){
cout << "~Date()" << endl;
}
};
class Person{
int age;
Date date;
public:
Person(){
cout << "Person()" << endl;
}
~Person(){
cout << "~Person()" << endl;
}
};
int main(){
Person *p=static_cast<Person*>malloc(sizeof(Person));
free(p);
Person *p2 = new Person();
delete p2;
}
五、拷贝构造函数
5.1 概念
本质上是一个构造函数 用拷贝数据的方式来构建对象
5.2 语法
Person(const Person&p){
}
如果不给一个类型提供拷贝构造函数 系统就默认提供一个拷贝构造函数
#include <iostream>
using namespace std;
class Person{
string name;
int age;
public:
Person(string name,int age){
}
};
int main(){
Person p;
}
5.3 拷贝构造函数的调用时机
1、使用一个已经存在的对象 去创建另外一个对象
2、把对象传给一个函数的参数时
3、把一个对象 作为函数返回值时
4、为什么要有拷贝构造函数
系统默认提供的拷贝构造函数 完成的是数据的逐字节拷贝。
需要处理内存独立问题时 需要自定义拷贝构造函数。
#include <iostream>
using namespace std;
class Person{
string name;
int age;
public:
Person(string name="",int age=0):name(name),age(age){
}
void show() const{
cout << name << ":" << age <<endl;
}
/*写一个拷贝构造函数*/
Person(const Person& p){//2、把对象传给一个函数的参数时,此处使用引用
cout << "Person(Person)" << endl;
name=p.name;
age=p.age;
}
};
void showPerson(const Person& p){
p.show();
}
Person getPerson(const Person& p){//3、把一个对象 作为函数返回值时
return p;
}
/*去掉拷贝
const Person& getPerson(const Person& p){//3、把一个对象 作为函数返回值时
return p;
}
*/
Person getP(){
/*Person p;
return p;*/
/*匿名对象简化 编译器优化只有一次构造*/
return Person("qwer",123);
}
int main(){
Person pa("xiaoming",12);
Person pb=pa;//1、使用一个已经存在的对象 去创建另外一个对象
pb.show();
showPerson(pb);//2、把对象传给一个函数的参数时
Person p=getPerson(pa);
}
深拷贝和浅拷贝
#include <iostream>
using namespace std;
class Array{
/*最大容量*/
int cap;
/*多少个元素*/
int size;
/*真正存储数据的区域*/
int *data;
public:
Array(int cap=5):cap(cap),size(0){
date=new int[cap];
}
~Array(){
delete[] data;
}
Array(const Array& a){//深拷贝
cap=a.cap;
size=a.size;
/*重新申请内存空间*/
data=new int[cap];
/*复制数据*/
for(int i=0;i<size;i+){
data[i]=a.data[i];
}
}
};
int main(){
Array arra;
Array arrb=arra;
}
六、静态成员
6.1不需要对象 就可以调用函数,通过类型就可以完成这种函数的调用。
#include <iostream>
using namespace std;
class A{
public:
void fooa(/*A *this*/){//普通成员函数
cout << "fooa()" << endl;
cout << this->x << endl;
cout << thsi->y << endl;
}
static void foob(){
cout << "foob()" << endl;
//cout << x << endl;
cout << y << endl;
}
static void fooc(A *mythis){
cout << mythis->x << endl;
}
};
int A::y=1;
int main(){
A a;
a.fooa();
A::foob();
}
6.2静态成员变量
静态成员变量 是整个类型共用的变量。
普通成员变量 是对象独有的。
静态成员变量 必须在类外进行初始化。
class A{
int x;
/*静态成员变量*/
static int y;
};
/*基本类型赋值成零,类类型默认调用无参构造*/
静态成员变量类型 类名::变量名;
6.3静态成员函数 和 静态成员变量
静态成员函数中只能(直接)访问静态成员。
/*静态函数中没有this指针*/
不能直接访问非静态成员。
静态成员 就是受类名作用域和权限限制的全局数据。
6.4 单例模式的实现
一个进程中 这种类型的对象只有一个
#include <iostream>
using namespace std;
class Singleton{
private:
Singleton(){}
Singleton(const Singleton& s){}
static Singleton sig;
public:
static Singleton& getInstance(){
return sig;
}
};
Singleton Singleton::sig;//静态成员变量 必须在类外进行初始化
int main(){
Singleton& sig=Singleton::getInstance();
}