String类实现的一个简单Demo

一个简单的String类的实现,转载自:

http://www.ccs.neu.edu/home/sbratus/com1101/mystring.txt

//
//  myString is an (inefficient) implementation of a string class.
//  It's only purpose is to provide an example of dynamic memory
//  handling for a C++ class with intuitive copy semantics.
//
//  For a real implementation see  string  in your compiler's
//  include directory.
//
//  All critical functions print an alert when called. Run the test code
//  and observe the results.

//----------------------------------------------------------------------
//
// File  mystring.h  -- headers for class myString
//
//----------------------------------------------------------------------

#ifndef MY_STRING_H
#define MY_STRING_H


#include <iostream>

using namespace std;

// Helper functions:
//
// my_strlen : count the length of a string until a null char
//
// my_strncpy : copy n chars from source to destination

int my_strlen( char * ptr ){
  int len = 0;
  char * p = ptr;
  while( *p != '\0' ) {
    len++;
    p++;
  }
  return len;
}

void my_strncpy( char * ptr_dest, char * ptr_src, int n ){
  for( int i=0; i < n; i++ )
    ptr_dest[i] = ptr_src[i];
}

class myString {
  int length;               // length of the string
  char * buff;              // pointer to strorage
public:

  // Constructors: default, from a string literal (char*), copy constr.
  // When possible, constructors should use initialization lists rather
  // than assignments. Thus:
  //        buff( new char[length] )   in the init list is better that
  //        buff = new char[length]    in the body of the constructor,
  //   although they do the same thing -- allocate dyn. memory

  myString() : length(0), buff(NULL)
    {
      cout << "  myString default constr.\n";
    }

  myString( char* init_val ) :
    length( my_strlen(init_val) ),    // count the length of init value
    buff(   new char[length] )     // allocate storage
    {
      cout << "  myString( char * ) constr.\n";
      my_strncpy( buff, init_val, length );  // copy init value into storage
    }

  myString( const myString& other ) :
    length( other.length ),
    buff(   new char[length] )
    {
      cout << "  myString copy const.\n";
      my_strncpy( buff, other.buff, length );
    }

  ~myString()
    {
      cout << "  myString destr.\n";
      delete [] buff;
    }

  int size() { return length; }

  // operator= returns  myString&  to allow multiple assignments

  myString& operator= ( const myString& other )
    {
      cout << "  myString::operator=\n";
      if( this != &other ){          // guard against  a = a;
    delete [] buff;              // release old memory & then
    length = other.length;       // allocate new memory
    buff = new char[length];
    my_strncpy( buff, other.buff, length );
      }
      return *this;                  // return a reference to itself
    }                                // to allow a = b = c;

  // concatenation of strings; we should also handle chars.
  // notice that + is overloaded thrice:
  //    myString + myString,  myString + char, char + myString
  // making operator+ a _friend_ allows for all three types; while
  // the first two can be done with a _member_ as well, the last cannot!

  friend myString operator+( const myString& s1, const myString& s2 );
  friend myString operator+( const myString& s, char c );
  friend myString operator+( char c, const myString& s );

  friend ostream& operator<< ( ostream&, const myString& );

  // finally, we want to reveal characters of a string for lookup
  // and assignment (hence we return a _reference_ to a char!)

  char& operator[] (int index )
    {
      if( index < 0 || index > length ) {
    cerr << "Invalid index in myString::operator[]. Aborting...\n";
    exit(-1);   // exit immediately. This is BAD -- somebody has to
                // first deallocate the strings we allocated, or else
                // we have a memory leak!
      }
      return buff[index];
    }
};

// Notice that each one of these operators calls a constructor,
// so a new object (with its own private memory) is created each time.
// Most of the time it's a temporary that will shortly be destroyed.

myString operator+( const myString& s1, const myString& s2 )
{
  myString res;
  res.length = s1.length + s2.length;
  res.buff = new char[ res.length ];
  my_strncpy( res.buff, s1.buff, s1.length );
  my_strncpy( res.buff + s1.length,            // pointer arithmetic!
          s2.buff,
          s2.length );
  return res;
}

// implement the other two guys yourself

ostream& operator<< ( ostream& os, const myString& s )
{
  // print char after char from buff
  for( int i=0; i < s.length; i++ )  os.put( s.buff[i] );
  return os;         // this is to allow multiple <<, as in  cout << a << b;
}

#endif  // MY_STRING_H

//----------------------------------------------------------------------
//
// File  mystring-test.cc  (.cpp if Visual C++)   -- tests
//
//----------------------------------------------------------------------

void foo( myString& s );
void bar( myString  s );

int main(){

  // construction and initialization

  myString a = "Hello ";
  myString b = a;
  myString c;

  cout << a << b << c << endl;

  cout << "------------------------------------------" << endl;

  // value swap

  myString u = "123";
  myString v = "class";

  c = u;
  u = v;
  v = c;

  cout << u << v << c << endl;

  cout << "------------------------------------------" << endl;

  // creating a few temporaries and testing +

  myString w = a + u;

  cout << w << endl;

  cout << myString( "Beam me up" ) + myString( ", Scotty!") << endl;

  cout << "------------------------------------------" << endl;

  // a miracle: although operator= is defined only for another myString,
  // the following line has the same effect as
  //                                           a = myString( "Hi ");
  // Notice that a temporary is contsructed and then destroyed.
  // Lesson: C++ uses your constructor to construct objects as it sees fit.

  a = "Hi ";

  cout << a << b << endl;

  cout << "------------------------------------------" << endl;

  // Copy contructor is also used when passing parameters to functions
  // by value (but not by reference)

  myString x = "i am given to foo";
  myString y = "i am given to bar";

  foo( x );

  cout << "And now x is: " << x << endl;

  bar( y );                 // notice the call to the copy constr.

  cout << "And now y is: " << y << endl;

  cout << "------------------------------------------" << endl;

  // check operator[]

  myString t = "hello old friend.";
  t[0] = 'H';
  t[6] = 'O';
  t[10] = 'F';

  cout << t << endl;

  cout << "------------------------------------------" << endl;

  return 0;  // return 0 to signal normal completion to the OS
}

// both foo and bar attempt to clobber the string. See which one succeeds.

void foo( myString& s ){
  s = "FOO was here!";
}

void bar( myString s ){
  s = "BAR was here!";
}

//----------------------------------------------------------------------
//
//  Output of running  mystring-test  .
//
//----------------------------------------------------------------------
/*

  myString( char * ) constr.
  myString copy const.
  myString default constr.
Hello Hello
------------------------------------------
  myString( char * ) constr.
  myString( char * ) constr.
  myString::operator=
  myString::operator=
  myString::operator=
class123123
------------------------------------------
  myString default constr.
  myString copy const.
  myString destr.
Hello class
  myString( char * ) constr.
  myString( char * ) constr.
  myString default constr.
  myString copy const.
  myString destr.
Beam me up, Scotty!
  myString destr.
  myString destr.
  myString destr.
------------------------------------------
  myString( char * ) constr.
  myString::operator=
  myString destr.
Hi Hello
------------------------------------------
  myString( char * ) constr.
  myString( char * ) constr.
  myString( char * ) constr.
  myString::operator=
  myString destr.
And now x is: FOO was here!
  myString copy const.
  myString( char * ) constr.
  myString::operator=
  myString destr.
  myString destr.
And now y is: i am given to bar
------------------------------------------
  myString( char * ) constr.
Hello Old Friend.
------------------------------------------
  myString destr.
  myString destr.
  myString destr.
  myString destr.
  myString destr.
  myString destr.
  myString destr.
  myString destr.
  myString destr.

*/

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值