类定义为:
测试函数声明:
结果分析:
首先,需要分清的就是赋值和初始化!
当“=”用来给一个变量提供初始值时,调用的是复制构造函数,进行的是初始化操作;
当在赋值表达式里使用时,调用的是operator=
不同的调用方法会产生完全不同的调用结果:
1
TestConstructor test;
test = testFunc();
这里的"="代表的是赋值操作,也就是调用operator=,结果为:
我们来分析一下输出:
第一行是声明test时调用了默认构造函数;
第二行是testFunc()中声明testInFunc时调用了默认构造函数;
第三行是testFunc()函数即将执行return语句时,先将testInFunc复制给系统生成的临时变量(return的工作原理:在返回时,将要返回的内容由系统复制一份,然后释放函数内的局部变量,在调用函数的那行语句执行完成后,将此临时变量析构掉),故调用了复制构造函数;
第四行是析构testFunc变量(是return做的第二件事);
第五行是执行赋值操作,将返回的临时变量赋值给test;
第六行是析构临时变量;
第七行是析构test。
2
TestConstructor b;
TestConstructor test=b;
这里的“=”表示初始化操作,需要调用复制构造函数,结果为:
第一行是声明b时调用了默认构造函数;
第二行是在初始化test时调用了复制构造函数;
第三、四行则是析构b,test。
3
TestConstructor b;
TestConstructor c;
c=b;
这里的"="表示赋值操作,此情况执行过程比较直观,只列出结果为:
4
TestConstructor test=testFunc();
这里的“=”表示初始化,结果为:
结果分析:
第一行为声明testFunc()函数中的局部变量testInFunc是调用了默认构造函数;
第二行是testFunc()函数即将执行return语句时,先将testInFunc复制给系统生成的临时变量(return的工作原理:在返回时,将要返回的内容由系统复制一份,然后释放函数内的局部变量,在调用函数的那行语句执行完成后,将此临时变量析构掉),故调用了复制构造函数;
第三行是析构testFunc变量(是return做的第二件事);
第四行是析构test(这个比较有意思,由第二种情况可知当用一个类变量来初始化另一个类变量时,应该调用复制构造函数,但是结果却显示并没有这么做,我没有细究,但猜测是编译器优化,直接将test指向了系统自动返回的临时变量?)
5
TestConstructor b;
testcanshu(b);//会调用复制构造函数,然后再析构掉参数
void testcanshu(TestConstructor b) { }
用类变量做形参,则会自动调用复制构造函数(形参是实参的一份拷贝!)
第一行是声明b调用了默认构造函数;
第二行则是将实参拷贝给形参时(可以认为是构造参数列表里的b),调用了复制构造函数;
第三行则是析构了形参;
第四行析构了b;
testcanshu1(b);//什么都不做
void testcanshu1(TestConstructor& b) {}
因为参数是引用,则参数就是实参本身,故什么都不调用,只构造了b和析构了b。
testcanshu2(b);
TestConstructor& testcanshu2(TestConstructor& b)
{
return b;
}
同上一种情况,虽然有return语句,但是因为返回的是引用,不存在析构的过程。
6
TestConstructor b;
TestConstructor temp=testcanshu3(b);
有前面可知,“=”代表了初始化操作,应该调用复制构造函数
TestConstructor testcanshu3(TestConstructor b)
{
return b;
}
分析:
第一行是声明b,调用了默认构造函数;
第二行是类变量做形参,需要调用复制构造函数;
第三行是函数即将执行return语句时,先将形参b复制给系统生成的临时变量(return的工作原理:在返回时,将要返回的内容由系统复制一份,然后释放函数内的局部变量,在调用函数的那行语句执行完成后,将此临时变量析构掉),故调用了复制构造函数;
第四行是析构了形参b ;(return语句做的第二件事情)
第五行是析构了return时返回的临时变量;
第六行是析构了temp (注意!如同情况4一样,=号并没有调用复制构造函数)
7
TestConstructor temp=testcanshu3(1);
TestConstructor testcanshu3(TestConstructor b)
{
return b;
}
结果分析:
第一行是构造形参b时调用了TestConstructor(int i)这个构造函数;
第二行和第三行是return做的两件事,通过前面几次,这个过程应该很明确了;
第四行是析构temp (= 还是初始化操作,同样的,还是没有调用复制构造函数)