前言
有了基本的构造函数、拷贝函数、析构函数
可以自己试着写个丐版的string。
正文
- hstring str(“哈哈哈”); //构造函数
- hstring strA(str); //拷贝函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| #pragma once class hstring{ public: hstring(){
}
hstring(const hstring &hs){
}
~hstring(){
} };
|
大概框架就是这样,但是要注意,套string就没意思了。
char或者char*的话要注意内存分配的事。
想了下大概是char*比较合适,毕竟初始化的时候鬼知道这个字符串多长。
然后提到长度,还要写个成员变量,和成员函数去统计出这个长度。
构造
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| #pragma once class hstring{ private: char *c_str; unsigned int len; unsigned int Length(const char *hs){ while (hs[this->len++]); return this->len; } public: hstring(){ this->len = 0; }
hstring(const char* hs){ c_str = new char[Length(hs)]; for (int i = 0; i < this->len; i++){ c_str[i] = hs[i]; } }
char *toShow(){ return c_str; }
unsigned int toLength(){ return this->len; }
~hstring(){ delete[] c_str; } };
|
1 2 3 4 5 6 7 8 9
| #include<iostream> #include"hstring.h"
int main(){ hstring str("hahah"); std::cout << str.toShow() << std::endl;
return 0; }
|
因为没涉及到重载,只能通过成员函数先打印将就一下了。
结果也是ok的,至于那个toLength是因为我记得string好像也有个调用可以显示长度的方法,就干脆放在public下面调用得了。
至于len本质上是存放长度肯定不希望被其他人调用就放在私有里面,然后Length的话,本质上跟sizeof有点相似,它会计算字符串结尾的\0
,想要strlen的效果就让返回值-1就行了。
至于中文占2个字节的问题先不考虑。
到这里构造没啥事了,下面就是拷贝的问题。
拷贝
拷贝就难在没有[]重载运算。hstring是自己定义的类。
你要想让hstring strA(str);
还要注意不能让两个地址相同,不然前面的被释放了,后面的就无效了。
1 2 3
| hstring(const hstring &hs){ c_str = hs; }
|
这样肯定行不通,c_str是char*类型,hs是hstirng类型的,强转上逻辑也不对,因为没有调出hs.c_str这种东西。
使用列表传递的话,就要再次调用toShow函数,但是这里的hs是const类型,所以toShow也要加上const
1 2 3 4 5 6
| hstring(const hstring &hs):hstring(hs.toShow()){ } char *toShow() const{ return c_str; }
|
这样编译是通过了,但是要看看效果。
看到效果ok。
印证
最后无非就是印证销毁的时候strA还是不是正常的。
这个讲道理是不好印证的,因为str先声明的,strA后声明的,你也没办法指定它执行析构函数,这个还是由编译器认的。
所以顺序上没法印证,那就只能通过改变str,查看strA的结果还是否相同,去印证是不是一个内存地址。
1 2 3 4 5 6 7
| void toRemake(const char *hs){ delete[] c_str; c_str = new char[Length(hs)]; for (int i = 0; i < this->len; i++){ c_str[i] = hs[i]; } }
|
还是老样子传递const char*, 然后先释放原有的内存,因为不能保证c_str是否之前分配过了,然后在赋予新的内存。老样子循环抄写hs,这里用不用memcpy都随便。
效果不同,说明strA和str使用的不是同一个内存。
完整的hstring.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| #pragma once #include<iostream> class hstring{ private: char *c_str; unsigned int len=0; unsigned int Length(const char *hs){ while (hs[this->len++]); return this->len; } public: hstring(){ }
hstring(const char* hs){ c_str = new char[Length(hs)]; for (int i = 0; i < this->len; i++){ c_str[i] = hs[i]; } }
hstring(const hstring &hs):hstring(hs.toShow()){ }
char *toShow() const{ return c_str; }
unsigned int toLength(){ return this->len; }
void toRemake(const char *hs){ delete[] c_str; c_str = new char[Length(hs)]; for (int i = 0; i < this->len; i++){ c_str[i] = hs[i]; } }
~hstring(){ delete[] c_str; } };
|
结语
优化空间肯定还有的,重载就是一个点。
还有就是功能上还是丐版阶段。