string类、拷贝构造函数、析构函数
#if 1
#include<iostream>
using namespace
class String {
char *data; //指向存放字符的内存块 // C风格的字符串
int n; //字符个数
// 构造函数(公开)
public:
String(const String &s) { //执行硬拷贝
cout << "拷贝构造函数!\n";
data = s.data;
n = s.n;
}
String(const char *s = 0) { //默认构造函数:不带参数或参数为默认值
// 如果传了参数,就不是默认构造函数了
if (s == 0) {
data = 0; n = 0; return;
}
// 如果 s != 0 执行下面
const char *p = s;
while (*p != '\0') p++; // 或者 while(*p)
n = p - s; // 字符个数
data = new char[n + 1]; //分配n+1个字符的内存空间
// 把s的值拷贝到data
for (int i = 0; i <= n; i++) { // i =n;相当于把接收字符'\0'也拷贝进去
data[i] = s[i]; // 或者循环结束后,加data[n] = '\0';
}
}
// 定义size成员
int size() { return n; }
// 定义下标运算符,要定义两个版本,一个是const版本,用于查询下标为i的字符
char operator[](int i)const { // 返回值 char 字符
if (i < 0 || i >= n) throw "下标非法";
return data[i];
}
//另一个版本,返回引用 &
char& operator[](int i) { // 返回值 char 字符
if (i < 0 || i >= n) throw "下标非法";
return data[i];
}
};
ostream & operator<<(ostream &o, String s) {
for (int i = 0; i < s.size(); i++)
cout << s[i];
return o;
}
int main() {
String str,str2("hello world"); // str不传参数,所以调用的是默认构造函数
str2[1] = 'E';
//没定义拷贝构造函数时,编译器会自动生成默认拷贝构造函数
// 执行硬拷贝
cout << str2 << endl;
String s3 = str2; //调用拷贝构造函数 两个指向同一个内存
cout << s3 << endl;
s3[3] = 'L'; //把S3第三个字符l改为L;
cout << s3 << endl;
cout << str2 << endl; // 发现str2也会跟着改变
}
#endif
上面的代码将 s3 = str2; 会调用默认构造函数实现硬拷贝,即两者指向同一个内存 那我们要重新写拷贝构造函数,使得data不是硬拷贝
C++的类String在定义类的对象的时候(String str,str2)会调用构造函数;那在销毁销毁的时候,会调用析构函数 (~String 不能带参数,也无返回类型)。 默认析构函数 ~String(){ }