07. this指针,构造和析构,new和delete
一.this指针
1.不同的对象,数据成员是独有的,成员函数是共享的
2.调用成员函数的时候,会默认传入this指针,this指针指向了调用函数的对象的首地址
3.this通过ecx传递,调用约定 __thiscall
4.成员函数的调用约定可以修改
5.this指针是class *const this
二.构造和析构
构造函数:函数名和类型相同,无返回值,可以有参数,可以有默认参数,可以重载
析构函数:函数名和类名相同,前面加~,无返回值,无参数,无法重载
构造和析构函数可以手动调用,调用格式:类名::函数名。例如:
auto foo=HasPtr::HasPtr("11");//手动调用构造函数
foo.HasPtr::HasPtr("22222");//再次手动调用构造函数
foo.~HasPtr();//手动调用析构函数
构造和析构的调用时机:
构造在对象声明周期的开始被调用
析构在对象声明周期的结束被调用
1.构造函数作用
当我们没有提供拷贝构造函数时,编译器会提供默认的拷贝构造函数,其功能是内存拷贝。
没有拷贝构造函数时,传递一个非引用类型的参数相当于调用memcpy来浅拷贝。
如果有拷贝构造函数,则调用拷贝构造函数。
2.拷贝构造函数调用的时机:
2.1定义一个类对象
2.2非引用传递类对象
2.3非引用返回类对象
3临时对象(无名对象)
3.1非引用返回类对象
3.2直接创建一个对象HasPtr()
class HasPtr {
public:
HasPtr(int *p = nullptr) :p(p) {
cout << "HasPtr(int *p=nullptr)" << endl;
}
HasPtr(const HasPtr &rhs) :p(rhs.p) {
cout << "HasPtr(const HasPtr &rhs)" << endl;
}
~HasPtr() {
cout << "~HasPtr()" << endl;
}
private:
int *p;
};
int main() {
HasPtr ptr;
f(ptr);
return 0;
}
三.new和delete
使用malloc在堆中手动实例化对象:
HasPtr *p = (HasPtr *)malloc(sizeof(HasPtr));
p->HasPtr::HasPtr("asdf");//手动调用构造函数
p->~HasPtr();//手动调用析构函数
free(p);
new和delete在堆中自动实例化对象:
HasPtr *p = new HasPtr("111");//先申请内存,再调用构造函数
delete p;//先调用析构函数,再释放内存
HasPtr 占用12字节

new[]和delete[]:
HasPtr *p = new HasPtr[5];//先申请内存,再调用构造函数
new[] 额外保存了对象个数:

强调:
new和delete配对使用
New[]和delete[]配对使用
二.默认构造函数和默认析构函数
1.没有提供构造函数时,编译器自动合成一个默认构造函数。
提供了构造函数时,编译器不再自动合成一个默认构造函数。
2.编译器生成默认构造函数的情况:
2.1父类有构造函数,子类没有构造函数
2.2类对象作为成员,此成员有默认构造函数
2.3类中有虚函数
3.编译器生成默认析构函数的情况:
3.1父类有析构函数,子类没有析构函数
3.2类对象作为成员,此成员有默认析构函数
3.3类中有虚函数

浙公网安备 33010602011771号