c++中比较常用的一种类型是字符串类型,平常都是调用"string.h" 头文件或<string>类库,这里简单的进行自定义。
首先编写String类,创建头文件String.h:
1 #include2 using namespace std; 3 4 class String 5 { 6 public: 7 String(const char *str = NULL); 8 String(const String &other); 9 ~String(void);10 String & operator =(const String &other);11 private :12 char *m_data;13 };
然后进行类成员函数的实现,创建源文件String.cpp:
1 #include "String.h" 2 #include3 using namespace std; 4 5 String::String(const char *str ) 6 { 7 if(str==NULL) 8 { 9 m_data=new char[1];10 *m_data='\0';11 }12 else13 {14 int length=strlen(str);15 m_data=new char[length+1];16 strcpy(m_data,str);17 }18 }19 20 String::String(const String &other)21 {22 int length=strlen(other.m_data);23 m_data=new char[length+1];24 strcpy(m_data,other.m_data);25 }26 27 String& String::operator=(const String &other)28 {29 if(this==&other)30 return *this;31 delete []m_data;32 int length=strlen(other.m_data);33 strcpy(m_data,other.m_data);34 return *this;35 36 }37 String::~String()38 { 39 delete[]m_data;40 }
1 #include2 #include"String.h" 3 using namespace std; 4 5 int main(void) 6 { 7 String s1("hello"); 8 String s2=s1; 9 String s3="world";//10 String s3=s1;//11 return 0;12 }
注意:复制构造函数和赋值函数的区别,拷贝构造函数是在对象被创建时被调用,而赋值函数只能被已经存在了的对象调用。
拷贝构造函数和赋值运算符重载有以下两个不同之处: (1)拷贝构造函数生成新的类对象,而赋值运算符不能。 (2)由于拷贝构造函数是直接构造一个新的类对象,所以在初始化这个对象之前不用检验源对象是否和新建对象相同。而赋值运算符则需要这个操作,另外赋值运算中如果原来的对象中有内存分配要先把内存释放掉 注意:当有类中有指针类型的成员变量时,一定要重写拷贝构造函数和赋值运算符,不要使用默认的。
//由于没有重载输入输出流运算符,所以没有进行数据的打印显示,有待于完善...
*****几点疑问:*****
1.为什么拷贝构造函数的参数类型必须是引用?
原因: 如果拷贝构造函数中的参数不是一个引用,即形如CClass(const CClass c_class),那么就相当于采用了传值的方式(pass-by-value),而传值的方式会调用该类的拷贝构造函数,从而造成无穷递归地调用拷贝构造函数。因此拷贝构造函数的参数必须是一个引用。 需要澄清的是,传指针其实也是传值,如果上面的拷贝构造函数写成CClass(const CClass* c_class),也是不行的。事实上,只有传引用不是传值外,其他所有的传递方式都是传值。
2.为什么重载赋值运算符返回的是对象的引用?
参见: 和 ,写的不错.