#ifndef STRING_COPY
#define STRING_COPY
#include <iostream>
#include <stdlib.h>
using namespace std;
class nString{
public:
nString(const char *str = NULL);//普通构造函数
~nString(void);
nString(const nString &str);//拷贝构造函数
nString & operator = (const nString &str);//赋值函数
friend ostream & operator << (ostream &os, const nString &str);
private:
char *m_data;
};
#endif//STRING_COPY
#include "stringCopy.hpp"
#include <stdio.h>
#include <string.h>
nString::nString(const char *str)
{
cout << "nString" << endl;
if (str == NULL)
{
m_data = new char[1];//对空字符串自动申请存放结束标志'\0'的
if (m_data == NULL)
{
perror("new");
return;
}
*m_data = '\0';
}
else
{
int length = strlen(str);
m_data = new char[length + 1];
if (m_data == NULL)
{
perror("new");
return;
}
strcpy(m_data, str);
}
}
nString::~nString()
{
if (m_data != NULL)
{
delete m_data;
m_data = NULL;
}
}
//拷贝构造函数
nString::nString(const nString &str)
{
cout << "default copy" << endl;
int length = strlen(str.m_data);
m_data = new char[length + 1];
if (m_data == NULL)
{
perror("new");
return;
}
strcpy(m_data, str.m_data);
}
//赋值函数
nString & nString::operator = (const nString &str)
{
cout << "=" << endl;
if (this == &str)//检查自赋值
{
return *this;
}
if (m_data != NULL)//释放之前的资源
{
delete m_data;
m_data = NULL;
}
int length = strlen(str.m_data);
m_data = new char[length + 1];
if (m_data == NULL)
{
perror("new");
return NULL;
}
strcpy(m_data, str.m_data);
return *this;//返回本对象的引用
}
ostream& operator << (ostream &os, const nString &str)
{
os << str.m_data;
return os;
}
测试
#include <iostream>
#include "stringCopy.hpp"
using namespace std;
int main()
{
nString a("hello");
nString b(a);
nString c = b;
c = a;
cout << a << " " << b << " " << c << endl;
return 0;
}
编译:g++ main.cpp stringCopy.cpp
测试结果:
结论:
nString c = b;对象从无到有,会调用构造函数,此时没有匹配的构造函数会找到默认的构造函数。
c = a;对象已经存在,不会再调用构造函数,此时执行的是赋值操作符的重载。
注:
拷贝构造函数访问了类的私有成员,为什么呢?
访问限制标号是针对类而不是针对一个类的不同对象,只要同属一个类就可以不用区分同一个类的不同对象。
因为nString(const nString &str) 是类的成员函数,所以有权限访问私有数据成员。
参考:https://blog.csdn.net/qq_34543927/article/details/114759736