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类中有虚函数

posted @ 2020-05-12 09:07  八转达人  阅读(268)  评论(0)    收藏  举报