用一个A的对象a1对另一个A的对象a2初始化时, 拷贝构造没有显式声明,编译器会自动产生,该函数会将a1的所有成员copy给a2
通过代码测验如下:
通过对象进行初始化
A的声明:
extern int Acount;
class A
{
public:
A();
~A();
};
A的实现:
#include "A.h"
#include<iostream>
using namespace std;
int Acount = 0;
A::A() {
Acount++;
cout << "after the constructor ,Acount="<<Acount << endl;
}
A::~A() {
Acount--;
cout << "after the deconstructor ,Acount=" << Acount << endl;
}
通过Acount来计算A的对象个数。
main函数如下:
f函数接受一个A的对象并返回一个A的对象
#include<iostream>
#include "A.h"
using namespace std;
A f(A x) {
cout << "before f()," << endl;
cout << "Acount=" <<Acount<< endl;
cout << "after f()," << endl;
return x;
}
int main() {
A h;
A a = f(h);
cout << "Acount=" <<Acount<< endl;
return 0;
}
运行结果:
after the constructor ,Acount=1 //产生对象h,调用构造函数,Acount++
before f(),
Acount=1 //在函数f中没有出现调用默认构造函数
after f(),
after the deconstructor ,Acount=0
Acount=0 //从此看出,f函数结束前x被析构,且对象a在创建时没有调用构造
after the deconstructor ,Acount=-1
after the deconstructor ,Acount=-2
对象x和a的创建没有使用默认构造函数
再次测试:
在A类中加一个有参构造(参数是A的一个对象):
A::A(const A& b){
Acount++;
cout << "after the constructor ,Acount=" << Acount << endl;
}
运行结果
after the constructor ,Acount=1
after the constructor ,Acount=2
before f(),
Acount=2
after f(),
after the constructor ,Acount=3
after the deconstructor ,Acount=2
Acount=2
after the deconstructor ,Acount=1
after the deconstructor ,Acount=0
最后,结果为0,说明x和a的创建是通过A(const A& x)来进行构造的。
A(Const A& x)被称为拷贝构造。
拷贝构造何时调用:1.直接初始化时 2.调用函数时(像上文的f函数的调用将h的成员拷贝给形参)
拷贝构造是成员之间的拷贝(不是字节上的)
测验如下:
extern int num;
class A
{
public:
A(int* num);
int* p;
};
#include "A.h"
#include<iostream>
using namespace std;
A::A(int* num):p(num) {
cout << p << "\t" << *p << endl;
}
#include "A.h"
#include<iostream>
using namespace std;
int num = 10;
int main() {
int* num_p = #
A a1(num_p);
A a2(a1);
cout << a1.p << "\t" << *a1.p << endl;
cout << a2.p << "\t" << *a2.p << endl;
return 0;
}
结果:
00007FF74F84D000 10
00007FF74F84D000 10
00007FF74F84D000 10
即a1和a2中的p指向同一个位置。
为了安全性,我们希望a1和a2中指针所指的地方不同,但内容相同。为此加一个自己写的拷贝构造
int num_;
A::A(const A& a) {
num_ = *a.p;
p = &num_;
}
00007FF7DC8CE000 10
00007FF7DC8CE000 10
00007FF7DC8CE184 10
技巧:不管有用没用,在c++中没写一个类都列出三个函数:deconstructor,virtual deconstructor,拷贝构造函数。