拷贝构造的形式,何种情况会调用拷贝构造。
1.构造副本
2.以值的方式传参
3.以值的方式返回
缺省的拷贝赋值只能实现浅拷贝,因此会带来对象与其副本之间的指针耦合问题,为了实现深拷贝,就需要自己定义拷贝赋值,以获得完整意义上的对象副本。
实现步骤:
1)防止自赋值
2)释放原内存
3)分配新内存
4)获得新数据
5)返回自引用
练习:实现一个String类,可以通过C风格的字符串(指向\0结尾的字符串的指针)进行构造,支持拷贝构造和拷贝赋值,如果使用了动态内存分配,还需要提供析构函数。此外还要支持获得C风格字符串的接口c_str()
#include <iostream>
#include <cstring>
using namespace std;
class String {
public:
String (const char* str = NULL) :
m_str (strcpy (
new char[strlen (str ? str : "") + 1],
str ? str : "")) {}
~String (void) {
if (m_str) {
delete[] m_str;
m_str = NULL;
}
}
String (const String& that) ://拷贝构造函数
m_str (strcpy (
new char [strlen (that.m_str) + 1],
that.m_str)) {}
String& operator= (const String& that) {//拷贝赋值函数(深拷贝)
/* 菜鸟
m_str = new char[strlen (that.m_str) + 1];
strcpy (m_str, that.m_str);
*/
if (&that != this) {
/* 初级
delete[] m_str;
m_str = strcpy (
new char[strlen (that.m_str) + 1],
that.m_str);
*/
/* 中级
char str = new char[strlen (that.m_str)+1];
delete[] m_str;
m_str = strcpy (str, that.m_str);
*/
// 高级
String str (that);
swap (m_str, str.m_str);
}
return *this;
}
const char* c_str (void) const {
return m_str;
}
private:
char* m_str;
};
int main (void) {
String s1 ("Hello, World !");
cout << s1.c_str () << endl;
String s2 = s1;
cout << s2.c_str () << endl;
String s3, s4 ("http://blog.csdn.net/hnlyyk");
(s2 = s3) = s4;
cout << s2.c_str () << endl;
return 0;
}