变量,指针,引用
//拷贝与拷贝构造函数
//拷贝(copy):拷贝数据,拷贝内存
//=始终是在拷贝值,但是指针存储的是内存的地址,变量存储的是数据的值
//特别注意,在引用里面的拷贝是改变指向,没有复制的操作!
#include <string>
#include <iostream>
//拷贝与拷贝构造函数
//拷贝(copy):拷贝数据,拷贝内存
//=始终是在拷贝值,但是指针存储的是内存的地址,变量存储的是数据的值
//特别注意,在引用里面的拷贝是改变指向,没有复制的操作!
struct Vector2
{
float x,y;
};
int main()
{
//a,b是两个不同的变量,有两个内存地址,拷贝的是数据,因此a.x=2,b.x=5
Vector2 a={2,3};
Vector2 b=a;
b.x=5;
//如果分配在堆上,用指针,则不同 这里的拷贝是拷贝地址的数字,指向同一块内存
Vector2* c=new Vector2();
Vector2* d=c;
d->x=5;
std::cout<<a.x<<std::endl;
std::cout<<b.x<<std::endl;
std::cout<<(*c).x<<std::endl;
std::cout<<(* d).x<<std::endl;
std::cin.get();
}
//深拷贝:复制整个对象 通过 拷贝构造函数 实现(C++默认提供一个拷贝构造函数)
#include <string>
#include <iostream>
//深拷贝:复制整个对象 通过 拷贝构造函数 实现(C++默认提供一个拷贝构造函数)
class String
{
private:
char* m_Buffer;
unsigned int m_Size;
public:
String(const char* string)//用指针访问字符串字面量的首地址
{
m_Size=(int)strlen(string);
m_Buffer=new char[m_Size+1];//给一个空间给空终止符
memcpy(m_Buffer, string, m_Size);//拷贝的简单化操作
m_Buffer[m_Size]=0;//此时的长度+1后,从0开始,一共有string+1个字符串,最后一个是0,终止符
//验证
// std::cout<<strlen(m_Buffer)<<std::endl;
// std::cout<<m_Buffer[m_Size-1]<<std::endl;
// for (int i=0; i<m_Size; i++) {
// m_Buffer[i]=string[i];
// }
}
//拷贝构造函数
//String(const String& other)=delete;//不允许复制 string2=string就会报错
//深拷贝
String(const String& other)
:m_Size(other.m_Size)
{
std::cout<<"copy"<<std::endl;
m_Buffer=new char[m_Size+1];
memcpy(m_Buffer, other.m_Buffer, m_Size+1);//拷贝的简单化操作
}
~String()
{
delete [] m_Buffer;//new,要用delete!因为我们没有用智能指针啦
}
char& operator[](unsigned int index)
{
return m_Buffer[index];
}
friend std::ostream& operator<<(std::ostream& stream,const String& string);
};
//打印字符串
std::ostream& operator<<(std::ostream& stream,const String& string)
{
stream<<string.m_Buffer;//因为友元的设定,属于可以访问m_Buffer,然后把字符串流放进stream里
return stream;
}
void Print(const String& string)//如果不是引用传递,这里的string会通过拷贝传值,多调用copy
{
std::cout<<string<<std::endl;
}
int main()
{
String string="QingXiao";
String string2=string;//程序会崩溃。因为这里是char*的拷贝,两个指针指向了同一个内存地址,在释放的时候会两次调用析构函数,第一次后,内存已经释放了,第二次时,对应内存块不属于此程序控制,因此程序崩溃
string2[2]='b';//没有深拷贝函数之前,可以看到两个结果都是一样的
// std::cout<<string<<std::endl;
// std::cout<<string2<<std::endl;
Print(string);
Print(string2);
std::cin.get();//最终运行要按一下回车,才会看到崩溃结果
}
建议打断点看运行过程理解