析构函数
构造函数/析构函数
this指针
new/delete
本章讲授的主要内容是C++类的构造,其中牵涉到的概念有类的构造函数与析构函数,this指针与new、delete关键字。
构造函数/析构函数
在所有面向对象的语言中,为了方便管理对象的生命周期,会在对象生成时与对象销毁时调用两个特殊的函数,构造函数,析构函数,这两个函数通常不需要用户手动调用,交由编译器调用。
当构造函数被调用时,类已经生成,但其成员变量没有被初始化,因此通常在构造函数中对类成员进行初始化,而当析构函数被调用时,则表明对象被销毁,通常在此时对对象中的资源进行释放。
#include <iostream>
class Node{
public:
Node(){
value = 0;
size = 0;
buf = new char[1024];
}
~Node(){
if(buf != nullptr){
delete[] buf;
buf = nullptr;
}
}
private:
int value;
int size;
char *buf;
};
int main(){
//定义在栈中的对象,当其出作用域后,对象便会被析构。
Node node;//定义了一个在栈中的node对象,main函数结束时被析构
{
//在块作用域中定义了一个在栈中的node对象,当作用域结束,node2对象被释放
Node node2;
}
return 0;
}
this指针
C++中的关键字,出现在类的非静态成员函数调用中,表示调用函数的那个具体对象地址,类型为Type * const this
,显然,这是一个指针常量,无法被赋值。也只能在类的非静态成员函数中使用。
#include <iostream>
class Node{
public:
void showValue(){
cout<<this->value<<endl;
}
//通过强制指定的方式让对象调用函数变成标准调用约定,这是this指针值被当做函数参数push入栈(不过在某些编译器中,手动指定无效)
void __stdcall setValue(int v){
//this的值来着ecx寄存器,类型为 Node * const this
this->value = v;
}
Node(){
value = 0;
size = 0;
}
~Node(){
}
private:
int value;
int size;
};
int main(){
Node node;
//此函数只有一个函数参数,但是调用约定采用的是C++特有的__thiscall.
//这种调用约定是将this指针指通过ecx寄存器传递值,因此默认情况下是无法对this指针取地址的,用__thiscall调用约定而不用__stdcall的好处在1、与_stdcall栈结构保持一致。2、优化this传值效率
node.setValue(12);
node.showValue();//12
//__thiscall调用约定的this指针值被存放在ecx寄存器中,无法被修改,无法被取地址,无法被取内存值(正常途径下
return 0;
}
new、delete
C++中,对象既可以定义在栈中,又可以定义在堆中。C++中通过new
关键字来创建堆对象,返回对象的堆地址值,通过delete
关键字来释放堆对象。
同样都是创建堆内存,需要与malloc
与free
区分开来。
malloc
是C时代的函数,作用是用来创建堆空间,与面向对象的概念无关,因此malloc
函数也无法创建堆对象(不会调用类的构造函数),free
只是释放堆空间,不会析构对象。
#include <iostream>
class Node{
public:
Node(){
cout<<"node()"<<endl;
}
~Node(){
}
};
int main(){
//在堆中创建一个一个node对象,若不调用delete,则永远不会释放(除非进程退出
Node *node = new Node;
{
Node *node2 = new Node;//即使离开作用域,node2对象也不会释放
delete node2;
}
delete node;
//创建12个node对象,在堆上创建对象群时会在首地址的前面4个字节中存放对象群的总大小
Node *nodes = new Node[12];//Node()构造函数被调12次
delete[] nodes;//只能通过这种方式释放对象群,这种语法会找到堆空间中对象群的首地址处的前4个字节,从中取出对象群的大小,从而释放对象群
//delete nodes;闪退,通过这种方式是无法定位到正确的对象地址的,因此运行过程中出现闪退
//delete[] nodes;释放对象群时,从后往前,高地址处的对象被先释放,低地址处的对象被后释放.
return 0;
}
一览众山小
posted on 2021-12-28 00:33 shadow_fan 阅读(151) 评论(0) 编辑 收藏 举报