Share a correct way to write a string class in a C++ interview

  • 2020-04-02 01:55:04
  • OfStack

Specifically:

Variables can be defined as int types and can be assigned and copied.
Can be used as a function's argument type and return type.
The element type that can be used as a standard library container is the value_type for vector/list/deque. Key_type as STD ::map is a further requirement, omitted in this article.
In other words, your String will allow the following code to compile and run without memory errors.


void foo(String x)  
{  
}  

void bar(const String& x)  
{  
}  

String baz()  
{  
  String ret("world");  
  return ret;  
}  

int main()  
{  
  String s0;  
  String s1("hello");  
  String s2(s0);  
  String s3 = s1;  
  s2 = s1;  

  foo(s1);  
  bar(s1);  
  foo("temporary");  
  bar("temporary");  
  String s4 = baz();  

  std::vector<String> svec;  
  svec.push_back(s0);  
  svec.push_back(s1);  
  svec.push_back(baz());  
  svec.push_back("good job");  
} 

This article gives answers that I think are appropriate for an interview, emphasizing correctness and ease of implementation (there is no mistake about writing on the whiteboard) rather than efficiency. In a sense, it's time (speed) for space (simplicity).

The simplest String has only one char* member variable. The upside is that it's easy to implement, the downside is that some operations are more complex (for example, size() would be linear time). In order to write the code correctly during the interview, the String designed in this article has only one char* data_ member. And the rule invariant is as follows: the data_ of a valid string object is guaranteed not to be NULL, and the data_ ends in '\0' to facilitate the C language STR *() series of functions.

Next, you decide which operations to support. You will definitely need constructs, destructions, copy constructs, and assignments (formerly the big three, now copy control). If drilled a little deeper, C++11's move construct and move assignment can also be available. To make the point, this article does not consider overloads such as operator[].

This basically sets the code:


#include <utility>  
#include <string.h>  

class String  
{  
 public:  
  String()  
    : data_(new char[1])  
  {  
    *data_ = '0';  
  }  

  String(const char* str)  
    : data_(new char[strlen(str) + 1])  
  {  
    strcpy(data_, str);  
  }  

  String(const String& rhs)  
    : data_(new char[rhs.size() + 1])  
  {  
    strcpy(data_, rhs.c_str());  
  }  
    

  ~String()  
  {  
    delete[] data_;  
  }  

    
  String& operator=(String rhs) // yes, pass-by-value  
  {  
    swap(rhs);  
    return *this;  
  }  

  // C++ 11  
  String(String&& rhs)  
    : data_(rhs.data_)  
  {  
    rhs.data_ = nullptr;  
  }  

  String& operator=(String&& rhs)  
  {  
    swap(rhs);  
    return *this;  
  }  

  // Accessors  

  size_t size() const  
  {  
    return strlen(data_);  
  }  

  const char* c_str() const  
  {  
    return data_;  
  }  

  void swap(String& rhs)  
  {  
    std::swap(data_, rhs.data_);  
  }  

 private:  
  char* data_;  
}; 

Note a few points about the code:

Call new char[] only in the constructor and delete[] only in the destructor.
The assignment operator is written in the modern way recommended by the C++ programming specification.
Each function has only one or two lines of code and no conditional judgment.
Destructors do not have to check if data_ is NULL.
The constructor String(const char* STR) does not check the validity of STR, which is a subject of endless debate. STR is used in the initialization list, so it makes no sense to assert() in a function body.
This is probably the simplest String implementation.

Exercise 1: add operator==, operator < , operator[], etc.

Exercise 2: implement an int size_; Member version, space for time.

Exercise 3: the performance of direct insertion sort of String in C++11 is higher than that of C++98/03 due to the right value reference and moving semantics. (the standard library of g++ also USES this technique.)

Chen hao's note: in the meantime, you can take a look at my old article "(link: #)".

The original link: http://coolshell.cn/articles/10478.html


Related articles: