文章目录
函数功能
函数使用
在主函数内如何写?
设计函数参数
什么情况下需要调用拷贝构造函数?
深拷贝与浅拷贝
刨析函数内构造、拷贝构造、析构函数的执行过程
函数功能
函数使用
在主函数内如何写?
例:
设计函数参数
- 假设一个类为A类,该拷贝构造函数名与类名相同为A
- 1.假设参数类型为值类型,如下代码所示:
- 2.假设参数类型为指针类型
- 3.假设参数类型为引用类型,这就是正确答案~
什么情况下需要调用拷贝构造函数?
- 1.用已有对象去初始化本类的对象
-
class A
{
public:
A(int i=0,int j=0):m_i(i),m_j(j)//构造函数
cout<<"A"<<endl
A(const A &s):m_i(s,m_i),m_j(m_j)//拷贝构造函数
cout<<"A(A&)"<<endl;
private:
int m_i;
int m_j;
};
void main()
{
A a(2,6);//调构造函数
A b(a);//调用拷贝构造函数?
}
A b(a);//调用拷贝构造函数?
- 2.函数传参,类类型的值传递
- 3.是值返回的类类型的函数,从局部对象到临时时调用。
- ?有指针作为数据成员时,一般析构和拷贝构造函数程序员都要自己写
??深拷贝与浅拷贝
什么是浅拷贝:
- ?类提供的默认拷贝构造函数是浅拷贝,只拷贝值,如有右指针作为数据成员,则会导致两个对象的指针指向同一段内存,那么在析构的时候会出问题(因为指向同一段内存,在第一次析构时,把空间释放了,而同一段空间不能被两次释放,就会报错),基于该问题就引出了深拷贝。
什么时候需要深拷贝?
- 由指针作为数据成员,而且用本类的旧对象构造了新对象,则要写拷贝构造,给新对象的指针开辟和旧对象指针同样大小的内存单元,然后拷贝相同的值(不但拷贝值,而且拷贝资源)
如下代码所示:
- 将s进行深拷贝
-
A(constA &s):m_i(s,m_i),m_j(m_i)
{
m_name=new char[strlen(s.i)+1];//给新对象指针开辟和旧对象相同大小的内存空间
strcpy(m_i,s,m_i);//拷贝值
}
刨析函数内构造、拷贝构造、析构函数的执行过程
用如下代码举例,分析输出结果:
class A
{
public:
A(int i=0,int j=0):m_i(i),m_j(j)//构造函数
cout<<"A"<<endl
A(const A &s):m_i(s,m_i),m_j(m_j)//拷贝构造函数
cout<<"A(A&)"<<endl;
~A()//析构函数
cout<<"A(A&)"<<endl;
pirint()
{
cout<<m_i<<" "<<m_j<<" "<<endl;
}
private:
int m_i;
int m_j;
};
void Test(A t)
{
cout<<"Test:"<<endl;
t.print();//调用输出函数
}
A fn()
{
A d(10,12);
return d;
}
void main()
{
A a(2,6);//调构造函数
A b(a);//调用拷贝构造函数?
A c(9,3);//调构造函数
Test(c);//调test函数
c=fn();
cout<<"main end"<<endl;
}
执行结果:
解释:
- 对象a在定义时依次调用1次构造函数A
- 用a对b复制,调用1次拷贝构造函数A(A&)
- 对象c在定义时依次调用1次构造函数A
- Test函数内,将实参c传给Test内的形参t(形参开辟空间是在函数调用时开辟,接收实参值),从实参c到形参t,调用1次拷贝构造函数A(A&),以及输出一次函数内部的Test:,然后调用printf函数输出t的值,m_i=9,m_j=3;此时,t的作用域消失,析构t~A93
- 在执行fn()时,fn内定义对象d,调用一次构造函数A;return d时,d作为局部变量,出了作用域fn()之后就不起作用了,因此需要用一个临时变量temp保存值,用局部对象temp将值带回给主函数。因此,在该阶段,首先d->temp,调用一次拷贝构造函数A(A&),然后d消失调用一次析构函数~A1012;temp->带回到主函数c内,调用一次拷贝构造函数A(A&)(解释一下这个为什么没有输出,因为现在编译器都优化了,实际是调用了,但随着编译器逐渐高级,编译器对其优化,没有必要再执行拷贝这一步)然后temp消失调用一次析构函数~A1012;然后执行“main end”,最后,主函数内变量作用域消失,根据析构函数的顺序,先构造的后析构,依次是c,b,a,~A93,~A26,~A26
|