#include<iostream>
using namespace std;
class point
{
public:
point(int xx, int yy)
{
x = xx;
y = yy;
}
/* point(point &t)
{
x = t.x;
y = t.y;
printf("called\n");
}
*/
void change(int xx, int yy)
{
x = xx;
y = yy;
}
void show()
{
printf("%d %d\n", x, y);
}
private:
int x;
int y;
};
int main()
{
point p(2, 3); // 随便定义个普通变量
point t = p; // 让一个类的变量p赋值给另一个类的变量t
// 说明C++的类里面本来就有默认的拷贝构造函数
/*
先看构造函数
比如class ZZ
{
public:
ZZ(int xx, int yy)
{
x = xx;
y = yy;
}
private:
int x;
int y;
}
构造函数的意思是说创建一个类的实例的时候用的函数,
那么上面的构造函数可以这样看待:
Z(int xx, int yy)
{
创建的变量的x = 参数xx;
创建的变量的y = 参数yy;
}
那么再来看拷贝构造函数:
ZZ(point &z)
{
创建的变量的x = z.x;
创建的变量的y = z.y;
}
说白了不过就是一个东西(类的实例)里面有很多变量,
然后写一个函数让这个东西的全部变量赋值给另一个东西(类的实例),
如此而已。
区别就是默认的拷贝构造函数,系统自带,就好像默认构造函数一样是隐藏着的。
功能上只是复制一下变量而已。
自定义的拷贝构造函数能自己定义语句而已。
举例一个自定义拷贝构造函数(花哨一点):
ZZ(point &z)
{
x = z.x + 1;
y = z.y + 1;
printf("克隆了一个类的实例,新的实例中,所有变量值增1\n");
// 假设这个类里面还有个字符串变量,值是Annie
// 那还可以这样写:str = z.str + "(cloned)";
// 那么新的变量中的str变量就会是: Annie(cloned)
// 实际上就是在复制成员变量的时候按照想法改改而已。还可以只复制一部分的变量,剩下的留空。
}
*/
// 再来想一个问题:用完拷贝构造函数以后,新的实例和原来的实例完全独立吗?
// 写个代码验证一下
point before(5, 5);
point after = before;
before.change(10, 10);
after.show(); // 结果是5 5
// 答案:略
return 0;
}
/*
总结:
写出一个什么样的类是用户自定义的,
编译器本来就没能力处理用户自定义的东西,
point a = b;
像这样的语句,不要想当然的认为编译器会像int、double的赋值处理一样简单。
就因为编译器本身没能力处理除了基本类型以外的东西,所以才会有拷贝构造函数的存在,
这个函数附属于所有用户写出的类中,因此才能让类的变量随意以整体复制(每个类变量都有那么多成员变量,哪那么好复制?)
只不过在这样的基础上,考虑到写代码的需要,把拷贝构造函数设为用户可以自定义而已。
书上写的“以下三种情况会用到拷贝构造函数”,其本质上都是在需要将一个实例复制到另一个实例的时候,
需要调用拷贝构造函数。所以条件有两个:
①、数据要从一个地方(类变量)传到另一个地方(类变量)
②、 被传递的变量(即目的地的那个类实例)是新创造的
对第二点代码上的理解:
point a, b;
a = b; // a早就创建出来了,所以不符合第二点,没调用拷贝构造函数。
point a;
point b = a; 会调用拷贝构造函数,原因不解释了。
*/
using namespace std;
class point
{
public:
point(int xx, int yy)
{
x = xx;
y = yy;
}
/* point(point &t)
{
x = t.x;
y = t.y;
printf("called\n");
}
*/
void change(int xx, int yy)
{
x = xx;
y = yy;
}
void show()
{
printf("%d %d\n", x, y);
}
private:
int x;
int y;
};
int main()
{
point p(2, 3); // 随便定义个普通变量
point t = p; // 让一个类的变量p赋值给另一个类的变量t
// 说明C++的类里面本来就有默认的拷贝构造函数
/*
先看构造函数
比如class ZZ
{
public:
ZZ(int xx, int yy)
{
x = xx;
y = yy;
}
private:
int x;
int y;
}
构造函数的意思是说创建一个类的实例的时候用的函数,
那么上面的构造函数可以这样看待:
Z(int xx, int yy)
{
创建的变量的x = 参数xx;
创建的变量的y = 参数yy;
}
那么再来看拷贝构造函数:
ZZ(point &z)
{
创建的变量的x = z.x;
创建的变量的y = z.y;
}
说白了不过就是一个东西(类的实例)里面有很多变量,
然后写一个函数让这个东西的全部变量赋值给另一个东西(类的实例),
如此而已。
区别就是默认的拷贝构造函数,系统自带,就好像默认构造函数一样是隐藏着的。
功能上只是复制一下变量而已。
自定义的拷贝构造函数能自己定义语句而已。
举例一个自定义拷贝构造函数(花哨一点):
ZZ(point &z)
{
x = z.x + 1;
y = z.y + 1;
printf("克隆了一个类的实例,新的实例中,所有变量值增1\n");
// 假设这个类里面还有个字符串变量,值是Annie
// 那还可以这样写:str = z.str + "(cloned)";
// 那么新的变量中的str变量就会是: Annie(cloned)
// 实际上就是在复制成员变量的时候按照想法改改而已。还可以只复制一部分的变量,剩下的留空。
}
*/
// 再来想一个问题:用完拷贝构造函数以后,新的实例和原来的实例完全独立吗?
// 写个代码验证一下
point before(5, 5);
point after = before;
before.change(10, 10);
after.show(); // 结果是5 5
// 答案:略
return 0;
}
/*
总结:
写出一个什么样的类是用户自定义的,
编译器本来就没能力处理用户自定义的东西,
point a = b;
像这样的语句,不要想当然的认为编译器会像int、double的赋值处理一样简单。
就因为编译器本身没能力处理除了基本类型以外的东西,所以才会有拷贝构造函数的存在,
这个函数附属于所有用户写出的类中,因此才能让类的变量随意以整体复制(每个类变量都有那么多成员变量,哪那么好复制?)
只不过在这样的基础上,考虑到写代码的需要,把拷贝构造函数设为用户可以自定义而已。
书上写的“以下三种情况会用到拷贝构造函数”,其本质上都是在需要将一个实例复制到另一个实例的时候,
需要调用拷贝构造函数。所以条件有两个:
①、数据要从一个地方(类变量)传到另一个地方(类变量)
②、 被传递的变量(即目的地的那个类实例)是新创造的
对第二点代码上的理解:
point a, b;
a = b; // a早就创建出来了,所以不符合第二点,没调用拷贝构造函数。
point a;
point b = a; 会调用拷贝构造函数,原因不解释了。
*/