手撕string(为了方便测试加上了输出)
class String{
private:
char* m_data;
public:
String(const char* cstr);//默认构造
String(const String& str);//拷贝构造
String& operator=(const String& str);//拷贝赋值
//为什么加&?因为operator=最后要返回的不是临时变量,是本来就存在的
~String();//析构
char* get_c_str()const{
return m_data;
}
};
#include<cstring>//包含了strlen、strcpy函数(其实也应该手撕的)
//“建议”编译器将此函数变为内联函数,编译器自己会做决定
inline String::String(const char* cstr=0){
cout<<"is default"<<endl;
if(cstr){
m_data=new char[strlen(cstr)+1];
strcpy(m_data,cstr);
}else{
m_data=new char[1];
*m_data='\0';
}
}
inline String::~String(){
cout<<"is delete"<<endl;
delete[] m_data;
}
inline String::String(const String& str){
cout<<"is copy constructor"<<endl;
m_data=new char[strlen(str.m_data)+1];
strcpy(m_data,str.m_data);
}
inline String& String::operator=(const String& str){
cout<<"is ="<<endl;
//考虑是不是自我赋值
if(this==&str)return *this;
delete[] m_data;
m_data=new char[strlen(str.m_data)+1];
strcpy(m_data,str.m_data);
return *this;//可以传值也可以传引用
}
inline ostream& operator<<(ostream& os,const String& str){
return os<<str.get_c_str()<<endl;
}
测试
int main(){
String test="Hello";
String a;
String b=a;
String c;
c=test;
{
String d;
String f(c);
static String s="Hell!";
}
//cout<<s<<endl;//编译会报错,因为s的作用域已经在上一行结束
cout<<c<<endl;
return 0;
}
运行结果
可以看到s在出了{}范围后就无法再调用(已经出作用域了)但是并没有在作用域结束后就析构,而是在程序执行结束才析构。