序:
说实话,博主卡了一天,哎,老了。。。。理解能力不行。有时候还想着先跳过把,结果下班后,还在纠结是不是自己打开的方式不对,这不,刚理解了点,回来写下笔记,因为初学c++,所以说的可能没那么准确,不对的地方,请多包涵,也是只是想说怕哪天忘记了回头来看下笔记估计能想起来。
看完博文,博主希望你能理解下几个点
1、拷贝构造函数是什么玩意。
2、非得用他吗,解决啥痛点。
3、怎么写!
正文
先跟着博主思路来吧,说道哪,理解到哪。
1、首先,一下是一个类Cyc,主要实现 打印a,b的操作
#include <iostream>
// #include <windows.h>
using namespace std;
// #include "head.h"
class Cyc{
int a,b;
public:
Cyc(int x,int y){
a=x;b=y;
};
void getAB(){
cout<<"a="<<a<<",b="<<b;
};
};
// 程序的主函数
int main()
{
Cyc c(1,2);
c.getAB();
return 0;
}
2、我们现在main里 要在定义一个Cyc类的对象e,传参也是1,2 ,你干啥要弄两个传参一模一样的Cyc的对象?
举个例子,小明120斤,吃完了3个苹果后126;请问多了几斤?之前的c对象就是小明之前的体重,现在新建的e就是吃了3个苹果后的126,我要知道多了几斤,就要用126-120,你理解下这段话,就能理解博主的意图,意思就是说,对象e的作用是进过一段计算后,和对象c来对比的!
你理解了我新建2个两个一模一样的Cyc对象的目的后,咱们看下面的代码
#include <iostream>
#include <windows.h>
using namespace std;
// #include "head.h"
class Cyc{
int a,b;
public:
Cyc(int x,int y){
a=x;b=y;
};
void getAB(){
cout<<"a="<<a<<",b="<<b<<endl;
};
};
// 程序的主函数
int main()
{
Cyc c(1,2);
c.getAB();
Cyc e(1,2);
e.getAB();
return 0;
}
嗯,到这里你会发现一个问题。看下面git演示,你定义c和e对象他们一样要走一遍构造函数,也就是走了2次!!!
3、既然 Cyc c和Cyc e传参都是(1,2),我为啥要构造两次,我直接让e 拷贝一次c的值就好了呀,这个拷贝的过程就要在拷贝构造函数里执行,先看下面代码
#include <iostream>
#include <windows.h>
using namespace std;
// #include "head.h"
class Cyc{
int a,b;
public:
Cyc(int x,int y){
a=x;b=y;
cout<<endl;
};
Cyc(const Cyc &obj){
a=obj.a;
b=obj.b;
};
void getAB(){
cout<<"a="<<a<<",b="<<b<<endl;
};
};
// 程序的主函数
int main()
{
Cyc c(1,2);
c.getAB();
Cyc e=c;
e.getAB();
return 0;
}
看下图,拷贝构造函数的作用就在这里。只进来一次构造函数。但是c和e对象值都初始化了!好了,别急继续往下,看
----------------分割线----------------
4、为啥你在网上教程里,上来就看到 指针*号如下,干啥用的,非用不可吗?
来,我们构建以下场景!!!!!!!!
题目,我要定义A类的两个变量 a,和b, 手动输入 一串英文字符串,不管输入啥,打印出来
a的首字母都要改成q,(其实模拟首字母大写的意思,反正就是改变了),然后 b拷贝了a,但是b的首字母还是原来的(也就是用户输入啥,b就是啥);
你们自己做看看,然后看看下面博主写的代码,你去理解下博主代码的意思!
#include <iostream>
#include <windows.h>
using namespace std;
#define MAX 20
class A{
char *str;
public:
A(char *sstr){
str=new char[MAX];//开辟10个char 内存空间的
strcpy(str,sstr);
};
//修改 字符串
void edit(){
str[0]='q';
};
//打印 字符串第一个字符
void getNext(){
cout <<*str<<endl;
};
~A(){
delete [] str;//释放内存
}
};
// 程序的主函数
int main()
{
SetConsoleOutputCP(65001);
char c[MAX];
cout<<"请输入用户名(英文):";
cin.get(c,MAX);
A a(c);
A b=a;
cout<<"修改前a的第一个字符是"<<endl;
a.getNext();//修改前打印a第一个字符
a.edit();//修改a
cout<<"修改a后a的第一个字符是"<<endl;
a.getNext();//打印a第一个字符
cout<<"b第一个字符也跟着变了"<<endl;
b.getNext();//打印b第一个字符
return 0;
}
正常没拷贝函数的话,他们的*str指针都指向同一个char[],的第一个位置,是同一个!!!!
这么说,可能会好理解写,str存了一个字符串,*str是指针,指向字符串第一个字符串,A b=a;所以 b的*str也指向了a *str所指向的这个字符。所以a *str指向改变了之后b也跟着变,博主理解 不懂对不对,感觉应该是 b的*str→a的*str->"cyc",也就是**str.(个人理解,不懂对错,手下留情。),因为这么理解好记点。
那怎么办,拷贝构造函数!!!;
#include <iostream>
#include <windows.h>
using namespace std;
#define MAX 20
class A{
char *str;
public:
A(char *sstr){
str=new char[MAX];//开辟10个char 内存空间的
strcpy(str,sstr);
};
A(const A &obj){
str =new char[MAX];
strcpy(str,obj.str);
};
//修改 字符串
void edit(){
str[0]='q';
};
//打印 字符串第一个字符
void getNext(){
cout <<*str<<endl;
};
~A(){
delete [] str;//释放内存
}
};
// 程序的主函数
int main()
{
SetConsoleOutputCP(65001);
char c[MAX];
cout<<"请输入用户名(英文):";
cin.get(c,MAX);
A a(c);
A b=a;
cout<<"修改前a的第一个字符是"<<endl;
a.getNext();//修改前打印a第一个字符
a.edit();//修改a
cout<<"修改a后a的第一个字符是"<<endl;
a.getNext();//打印a第一个字符
cout<<"b指向第一个字符不变"<<endl;
b.getNext();//打印b第一个字符
return 0;
}
好了,博文原创,我估计这样写完,几年后在回来看,我自己应该可以理解的了。