C++沉思录笔记 —— 第二十五章:库设计就是语言设计
#include <cstring>
#include <iostream>
using namespace std;
class String{
public:
String(const char* p){
sz = strlen(p);
data = new char[sz + 1];
strcpy(data, p);
}
~String() { delete[] data; }
operator char*() { return data; } //类型转换函数的定义,String类型可自动转换为char*类型
private:
int sz;
char* data;
};
int main(int argc, char const *argv[])
{
const char* p = "helloworld";
String s(p);
if(s)
cout << s << endl;
return 0;
}
以上有operator char*的返回值被交由用户去承担,这就是设计的不合理处。
第二版设计:
class String{
public:
String(const char* p){
sz = strlen(p);
data = new char[sz + 1];
if(data == 0)
error();
else
strcpy(data, p);
}
~String() { delete[] data; }
operator char*() { return data; }
private:
int sz;
char* data;
};
此版设计中error能否返回给用户,都存在问题。
class String{
public:
String(const char* p){
sz = strlen(p);
data = new char[sz + 1];
if(data == 0)
error();
else
strcpy(data, p);
}
~String() { delete[] data; }
int valid() { return data != 0; }
operator char*() { return data; }
private:
int sz;
char* data;
};
第四版设计:
#include <cstring>
#include <iostream>
using namespace std;
class String{
public:
String(const char* p){
sz = strlen(p);
data = new char[sz + 1];
if(data == 0)
throw bad_alloc();
else
strcpy(data, p);
}
~String() { delete[] data; }
operator char*() { return data; }
private:
int sz;
char* data;
};
int main(int argc, char const *argv[])
{
const char* p = "helloworld";
try{
String s(p);
cout << s << endl;
}catch(bad_alloc){
return -1;
}
return 0;
}
这样的方式使用异常会极大地简化我们的程序,因为只要String存在,就能保证已经成功分配了String的内存。所以,不用在String类的别的地方检查内存耗尽了。
#include <iostream>
#include <cstring>
using namespace std;
class String{
public:
friend String operator+(const String& op1, const String& op2);
friend int operator==(const String& op1, const String& op2);
friend ostream& operator<<(ostream& os, const String& s);
String(): data(new char[1]){
sz = 0;
*data = '\0';
}
String(const char* p){
assign(p, strlen(p));
}
String(const String& s){
assign(s.data, s.sz);
}
String& operator=(const String& s){
if(this != &s){
delete[] data;
assign(s.data, s.sz);
}
return *this;
}
operator const char*() const { return data; }
//const char* make_cstring() const { return data; }
int length() const { return sz; }
void make_cstring(char* p, int len) const{
if(sz <= len)
strcpy(p, data);
else
throw("Not enough memory supplied");
//...
}
String& operator+=(const String& s){
char* odata = data;
assign(data, sz + s.sz + 1);
strcat(data, s.data);
delete[] odata;
return *this;
}
~String() { delete[] data; }
private:
int sz;
char *data;
void assign(const char* s, unsigned len){
data = new char[len + 1];
if(data == NULL)
throw bad_alloc();
sz = len;
strcpy(data, s);
}
};
String operator+(const String& op1, const String& op2)
{
String ret(op1);
ret += op2;
return ret;
}
int operator==(const String& op1, const String& op2)
{
return (strcmp(op1.data, op2.data) == 0);
}
ostream& operator<<(ostream& os, const String& s)
{
return os << s.data;
}
int main(int argc, char const *argv[])
{
String s("helloweiqianqian");
const char* p = "helloweiqianqian";
String t = p;
cout << t << endl;
cout << (s==t) << endl;
return 0;
}

浙公网安备 33010602011771号