一个自己实现的string

最近实现了一个string类,添加了一些c++11元素。

除了基本的构造析构函数,拷贝构造和赋值函数,另外添加移动拷贝和赋值函数。default是一个很方便的特性有木有。

 //default constructor
KianString()=default;

KianString(const char *c): ch_(0) {
  ch_ = (char*)malloc(sizeof(char)*(strlen(c)+1));
  strncpy(ch_, c, strlen(c)+1);
};

~KianString(){
  free(ch_);
}

//copy constructor
KianString(const KianString &str){
  ch_ = (char*)malloc(sizeof(char)*(str.size()+1));
  strncpy(ch_, str.ch_, str.size()+1);
}

//assign operator, is ok for both lvalue and rvalue!
KianString &operator=(KianString str) noexcept {
  swap(*this, str);
  return *this;
}

//move constructor
KianString(KianString &&str) noexcept : ch_(str.ch_) {
str.ch_ = NULL;
} 

赋值拷贝采用了copy and swap  idiom:

inline void swap(KianString &str1, KianString &str2){
  using std::swap;
  swap(str1.ch, str2.ch);
}

//assign operator, is ok for both lvalue and rvalue!
  KianString &operator=(KianString str) noexcept {
  swap(*this, str);
  return *this;
} 

这样做有几个好处:

1.参数是传值调用,可以同时使用左值和右值,使用右值时自动调用移动拷贝函数

2.强异常安全的,异常只会发生在参数拷贝时,如果发生异常,不会影响this

3.值传递产生副本,所以自赋值也是正确的.

加法运算符重载:

KianString &operator+=(const KianString &str){
  ch = (char*)realloc(ch, strlen(ch)+str.size()+1);
  strcat(ch, str.ch);
  return *this;
}

template<typename T>
const T operator+(const T& lhs, const T& rhs) {
  return T(lhs) += rhs;    
}

1. 按照《c++编程规范》第27条,实现+运算符,先要实现+=,语义一致,便于维护

2. 将operator+定义为非成员函数,能够同时接受左右参数的隐式转换, 因为operator+=public,所以operator+不需要设成friend

3. 将operator+定义为template

 

code:

https://github.com/coderkian/kianstring

原文地址:https://www.cnblogs.com/coderkian/p/3721426.html