#include <iostream>
#include <string>
#include <memory>
class Entity
{
public:
int x, y;
Entity(int x, int y)
{
this->x = x;
this->y = y;
std::cout << "这是构造函数!!!" << std::endl;
}
~Entity()
{
std::cout << "这是析构函数!!!" << std::endl;
}
};
int main()
{
//Entity e1(2,5);
//Entity e2 = e1;
//e2.x = 9; //此时修改e2中属性变量的值不会影响e1,因为我们复制了一根Entity
Entity *e1 = new Entity(2, 5);
Entity* e2 = e1;
e2->x = 4; //此时修改e2中属性变量的值会影响e1,因为我们复制了e1的地址到e2,它两指向同样的地址
std::cin.get();
return 0;
}
手动实现String类来展示copy操作
#include <iostream>
#include <string>
#include <memory>
//自己实现string来更好的展示拷贝复制构造函数
class String
{
private:
char* m_Buffer;
unsigned int m_Size;
public:
String(const char* string)
{
m_Size = strlen(string);
m_Buffer = new char[m_Size+1]; //+1是因为要添加一个空终止符
memcpy(m_Buffer, string, m_Size);
m_Buffer[m_Size] = 0;
}
~String()
{
delete[] m_Buffer;
}
friend std::ostream& operator<<(std::ostream& stream, const String& string);
};
std::ostream& operator<<(std::ostream& stream, const String& string)
{
stream << string.m_Buffer;
return stream;
}
int main()
{
String s1 = "pcop";
/*
下面这种方式进行copy操作会导致程序崩溃,因为在此处=操作进行的是浅拷贝,
会导致两个String对象中的m_Buffer指向同一块内存地址,这样就会导致析构函数
会对同一块内存地址释放两次
*/
String s2 = s1;
std::cin.get();
return 0;
}
#include <iostream>
#include <string>
#include <memory>
//自己实现string来更好的展示拷贝复制构造函数
class String
{
private:
char* m_Buffer;
unsigned int m_Size;
public:
String(const char* string)
{
m_Size = strlen(string);
m_Buffer = new char[m_Size+1]; //+1是因为要添加一个空终止符
memcpy(m_Buffer, string, m_Size);
m_Buffer[m_Size] = 0;
}
//拷贝构造函数
String(const String& other)
:m_Size(other.m_Size)
{
m_Buffer = new char[m_Size+1];
memcpy(m_Buffer, other.m_Buffer, m_Size+1);
}
char& operator[] (int index)
{
return m_Buffer[index];
}
~String()
{
delete[] m_Buffer;
}
friend std::ostream& operator<<(std::ostream& stream, const String& string);
};
std::ostream& operator<<(std::ostream& stream, const String& string)
{
stream << string.m_Buffer;
return stream;
}
int main()
{
String s1 = "pcop";
/*
* 如果不是先上诉的拷贝构造函数
下面这种方式进行copy操作会导致程序崩溃,因为在此处=操作进行的是浅拷贝,
会导致两个String对象中的m_Buffer指向同一块内存地址,这样就会导致析构函数
会对同一块内存地址释放两次
*/
String s2 = s1;
/*
* 下面操作修改s2的时候s1的值也会修改,因为两个String对象的m_Buffer指向同一块内存
* 我们在复制中应该的操作是分配一块新的内存用来复制m_Buffer
*/
s2[2] = 'z';
//解决上诉方法可以通过深拷贝来完成,本示例中通过拷贝构造函数来实现
std::cout << s1 << std::endl;
std::cout << s2 << std::endl;
std::cin.get();
return 0;
}
#include <iostream>
#include <string>
#include <memory>
//自己实现string来更好的展示拷贝复制构造函数
class String
{
private:
char* m_Buffer;
unsigned int m_Size;
public:
String(const char* string)
{
m_Size = strlen(string);
m_Buffer = new char[m_Size+1]; //+1是因为要添加一个空终止符
memcpy(m_Buffer, string, m_Size);
m_Buffer[m_Size] = 0;
}
//拷贝构造函数
String(const String& other)
:m_Size(other.m_Size)
{
std::cout << "Copy String!!!" << std::endl;
m_Buffer = new char[m_Size+1];
memcpy(m_Buffer, other.m_Buffer, m_Size+1);
}
char& operator[] (int index)
{
return m_Buffer[index];
}
~String()
{
delete[] m_Buffer;
}
friend std::ostream& operator<<(std::ostream& stream, const String& string);
};
std::ostream& operator<<(std::ostream& stream, const String& string)
{
stream << string.m_Buffer;
return stream;
}
void PringString(const String& s)
{
std::cout << s << std::endl;
}
int main()
{
String s1 = "pcop";
/*
* 如果不是先上诉的拷贝构造函数
下面这种方式进行copy操作会导致程序崩溃,因为在此处=操作进行的是浅拷贝,
会导致两个String对象中的m_Buffer指向同一块内存地址,这样就会导致析构函数
会对同一块内存地址释放两次
*/
String s2 = s1;
/*
* 下面操作修改s2的时候s1的值也会修改,因为两个String对象的m_Buffer指向同一块内存
* 我们在复制中应该的操作是分配一块新的内存用来复制m_Buffer
*/
s2[2] = 'z';
//解决上诉方法可以通过深拷贝来完成,本示例中通过拷贝构造函数来实现
/*
* 如果 PringString(String& s)
以下PringString方法调用的时候都会调用String的拷贝构造函数,每次需要分配新的内存
会造成很大的性能浪费,我们只是想直接打印PringString方法的参数,不想通过复制。
所以在PringString参数传递是直接传递引用 PringString(const String& s)
*/
PringString(s1);
PringString(s2);
std::cin.get();
return 0;
}