【直击招聘C++】2.3 对象指针
阿里云国内75折 回扣 微信号:monov8 |
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6 |
2.3 对象指针
一、要点归纳
和普通变量的指针一样用户也可以定义对象的指针。对象指针训词创建它指向的实例然后通过对象指针操作这个指向的实例。
1.用new动态创建实例
可以用new运算符动态地创建对象指针指向的实例。在用new运算符创建对象实例匿名对象时同样要自动调用构造函数以便完成对象实例数据成员的初始化。
2.用delete销毁对象指针指向的实例
对于用new运算符动态创建的对象实例可以使用delete运算符销毁在销毁时会自动调用析构函数。若不使用delete运算符销毁在程序结束时该对象仍然存在并占用相应的存储空间即系统不能自动销毁动态创建的对象实例。例如如下示例
#include <iostream>
class Test
{
char name;
int x,y;
public:
Test(char na,int x1,int y1)//构造函数
{
name=na;x=x1;y=y1;
std::cout<<"调用"<<name<<"的构造函数"<<std::endl;
}
~Test()
{
std::cout<<"调用"<<name<<"的析构函数"<<std::endl;
}
void dispoint()
{
std::cout<<"("<<x<<","<<y<<")"<<std::endl;
}
};
int main(int argc, char const *argv[])
{
Test a('a',1,2),b('b',3,4);
Test *p=new Test('p',5,6);//通过对象指针p指向创建的匿名对象
std::cout<<"p:";p->dispoint();
delete p;
std::cout<<"a:";a.dispoint();
std::cout<<"b:";b.dispoint();
return 0;
}
输出如下
调用a的构造函数
调用b的构造函数
调用p的构造函数
p:(5,6)
调用p的析构函数
a:(1,2)
b:(3,4)
调用b的析构函数
调用a的析构函数
从程序的执行结果可以看到以下几点
- 当创建多个类对象时按她们创建的先后顺序调用构造函数如该程序中a\b\p的顺序调用构造函数
- 匿名对象必须使用delete运算符销毁在执行delete运算时会调用析构函数
- main函数执行完毕首先执行匿名对象的析构函数有delete操作再按类对象创建的相反次序调用它们的析构函数
归纳起来对于动态实例的创建和销毁其过程如下
- new的时候做两件事一是分配实例的内存空间二是调用构造函数进行数据成员的初始化
- delete的时候也做两件事一是调用析构函数做清理工作二是释放实例的内存空间。
二、面试真题解析
面试题1
【面试题】若Test是一个类名其有如下语句序列下面语句中调用构造函数的次数是2
Test c1, *c2;
Test *c3 = new Test;
Test &c4 = c1;
【答】定义c1对象调用一次构造函数为对象指针c3使用new运算符动态分配内存空间时调用一次构造函数而定义c1的引用c4时并不会调用构造函数。故只有两次
面试题2
【面试题】假设有类AB有相应的构造函数定义能执行以下语句
AB a(4),b(5),c[3],*p[2]={&a,&b}
执行完此语句后调用该类构造函数的次数是5
【答】ab各调用构造函数一次定义对象数组c时调用构造函数3次。定义对象指针数组p并初始化时并没有创建新的实例所以不会调用构造函数。
面试题3
已知A,B,C,D四个类问以下代码执行时析构函数的调用顺序是什么ABDC
C c;
void main()
{
A *pa=new A();
B b;
static D d;
delete pa;
}
以上各个类创建时调用构造函数的顺序是类C的全局对象c、pa指向的类A对象、类B的对象b和静态对象d。遇到delete pa语句时调用A的析构函数。程序结束调用b的析构函数。接着释放静态对象d调用D的析构函数最后释放全局对象c调用C的析构函数。