变量,指针,引用
//拷贝与拷贝构造函数
//拷贝(copy):拷贝数据,拷贝内存
//=始终是在拷贝值,但是指针存储的是内存的地址,变量存储的是数据的值
//特别注意,在引用里面的拷贝是改变指向,没有复制的操作!
#include <string>
#include <iostream>//拷贝与拷贝构造函数
//拷贝(copy):拷贝数据,拷贝内存
//=始终是在拷贝值,但是指针存储的是内存的地址,变量存储的是数据的值
//特别注意,在引用里面的拷贝是改变指向,没有复制的操作!
struct Vector2
{float x,y;};
int main()
{//a,b是两个不同的变量,有两个内存地址,拷贝的是数据,因此a.x=2,b.x=5Vector2 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();//最终运行要按一下回车,才会看到崩溃结果
}
建议打断点看运行过程理解