众所周知,构造函数的众多隐式性质经常让人感觉到很意外。
前段时间学习运算符的重载,对一些与构造函数相邻的“=”号打起了主意,今天决定用重载运算符的办法验证这些“=”究竟是构造函数的“邻居”(各自独立)还是“家人”(被编译器理解为构造函数的一部分)。试验代码如下:
#include <iostream>
using namespace std;
class Dog
{
public:
Dog():itsAge(4) {cout<<"Dog Constructor/n";}
Dog(int age):itsAge(age) {cout<<"Dog Constructor/n";}
int GetAge() {return itsAge;}
//定义一个只传递itsWeight的重载赋值运算符
void operator=(Dog & rhs){itsWeight=rhs.itsWeight;}
private:
int itsAge;
int itsWeight;
};
int main()
{
//Alex
Dog Alex;
Dog Wang(3);
Alex=Wang;
cout<<"Alex is "<<Alex.GetAge()<<" years old./n";
//Tom
Dog Tom=Dog(3);
cout<<"Tom is "<<Tom.GetAge()<<" years old./n";
//Bruce
Dog * Bruce=new Dog(3);
cout<<"Bruce is "<<Bruce->GetAge()<<" years old./n";
return 0;
}
运行结果如下:
Dog Constructor
Dog Constructor
Alex is 4 years old.
Dog Constructor
Tom is 3 years old.
Dog Constructor
Bruce is 3 years old.
在Alex身上发生的赋值是最常规的赋值,先分别构造了Alex和Wang两个Dog类实例, 再以Wang为Alex赋值,由于Dog类的重载赋值运算符被定义为只传递itsWeight,因此Wang的值为3的itsAge并未赋给Alex,Alex.itsAge仍为默认的4;
Tom被用来验证“默认构造函数=无名构造函数”这种形式的代码究竟是①调用了两次构造函数,然后将右边的对象赋值给左边;还是②只调用了一次构造函数。结果显示“=”右边无名Dog的itsAge传递到了左边,而我们定义的重载赋值运算符只能够传递itsWeight,可见此处的“=”并不是赋值运算符。我们还可以看到这句代码只调用了一次构造函数,且调用的是“=”右边的那种重载构造函数,把Dog Tom=Dog(3)看作Dog Tom(3)。
引入Bruce对本实验并无实际意义,只是为了说明类的指针与类的实例是两个不同的概念。Dog * Bruce=new Dog(3)实际的工作为先构造了一个itsAge为3的无名Dog实例,然后使用这一实例的地址对指针Bruce进行初始化。 注意:此处的“=”并非赋值运算符,编译器把这行代码理解为Dog * Bruce(new Dog(3))。
这是我的第一篇技术类博文,见识粗浅,如有错误,欢迎指出。本人也是编程新手,欢迎交流。