C++类参考设计

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wangell/article/details/38174699

以下摘自: c++ primer 第五版 中文版 第12章 类和动态内存分配

 本章开始变引出此类.

头文件stringbad.h实现:

#include <iostream>
#ifndef STRINGBAD_H_
#define STRINGBAD_H_

Class StringBad
{
private:
    char *str;
    int  len;
    static int num_strings;
    StringBad(const StringBad &st); // copy constructor function 拷贝构造函数
    StringBad & operator=(const StringBad &st); // assignment operator 赋值操作符
    StringBad & StringBad::operator=(const char *s); // assignment operator 赋值操作符
public:
    StringBad(const char *s);
    StringBad();
    ~StringBad();
    // frient function
    friend std::ostream & operator<< (std::ostream &os, const StringBad &st);
};


其中拷贝构造函数赋值操作符私有化是为了避免系统自动定义其为隐式成员函数,导致逻辑出现问题.

若将拷贝构造函数和赋值操作符public化,可参考以下实现.

StringBad::StringBad(const StringBad &st)
{
    num_strings++;
    len = st.len;
    str = new char [len+1];
    std::strcpy(str, st.str);
    std::cout<<num_strings<<" : \":<<str<<"\" object created\n";
}

StringBad & StringBad::operator=(const StringBad &st)
{
    if(this == &st)
        return *this;
    delete []str;
    len = st.len;
    str = new char [len+1];
    std::strcpy(str, st.str);
    return *this;
}

StringBad & StringBad::operator=(const char *s)
{
    delete []str;
    len = sd::strlen(s);
    str = new char [len+1];
    std::strcpy(str, s);
    return *this;
}

其中,赋值操作符:

        由于目标对象可能引用了以前分配的数据,所以函数应使用delete[]来释放这些数据.

        函数应当避免将对象赋值给自身;否则,给对象重新赋值之前,释放内存操作可能删除对象的内存.

        函数返回一个指向调用对象的引用.


正确的string实现

// string1.h
#include <iostream>
using std::ostream;
using std::istream;

#ifndef STRING1_H_
#define STRING1_H_

class String
{
 private:
  char *str;              // pointer to string
  int len;                // length of string
  static int num_strings; // number of objects
  static const int CINLIM = 80; // cin input limit
 public:
  // constructors and other methods
  String(const char *s); // constructor
  String();              // default constructor
  String(const String&); // copy constructor
  ~String();             // destructor
  int length() const {return len;}
  // overloaded operator methods
  String & operator=(const String&);
  String & operator=(const char*);
  char & operator[] (int i);
  const char & operator[] (int i) const;
  // overloaded operator friends
  friend bool operator< (const String &st1, const String &st2);
  friend bool operator> (const String &st1, const String &st2);
  friend bool operator== (const String &st1, const String &st2);
  friend ostream & operator<< (ostream &os, const String &st);
  friend istream & operator>> (istream &is, String &st);
  // static function
  static int HowMany();
};

#endif
// string1.cpp
#include <cstring>
#include "string1.h"

using std::cin;
using std::cout;

//initializing static class member
int String::num_strings = 0;

// static method
int String::HowMany()
{
  return num_strings;
}

// class methods
String::String(const char *s) // construct String from C string
{
  len = std::strlen(s);  // set size
  str = new char[len+1]; // allot storage
  std::strcpy(str, s);   // initialize pointer
  num_strings++;         // set object count
}

String::String() // default constructor
{
  len = 4;
  str = new char[1];
  str[0] = '\0';        // default string
  num_strings++;
}

String::String(const String &st)
{
  num_strings++;            // handle static member update
  len = st.len;             // smae lenght
  str = new char[len+1];    // allot space
  std::strcpy(str, st.str); // copy string to new location
}

String::~String()           // necessary destructor
{
  --num_strings;            // required
  delete [] str;            // required
}

// overloaded operator methods

// assign a String to a String
String& String::operator= (const String &st)
{
  if(this == &st) return *this;
  delete [] str;
  len = st.len;
  str = new char[len+1];
  std::strcpy(str, st.str);
  return *this;
}

// assign a C string to a String
String& String::operator= (const char *s)
{
  delete [] str;
  len = std::strlen(s);
  str = new char[len+1];
  std::strcpy(str, s);
  return *this;
}

// read-write char access for non-const String
char& String::operator[] (int i)
{
  return str[i];
}

// read-only char access for const String
const char& String::operator[] (int i) const
{
  return str[i];
}

// overloaded operator friends
bool operator< (const String &st1, const String &st2)
{
  return (std::strcmp(st1.str, st2.str) < 0);
}

bool operator> (const String &st1, const String &st2)
{
  return (st2.str < st1.str);
}

bool operator== (const String &st1, const String &st2)
{
  return (std::strcmp(st1.str, st2.str) == 0);
}

// simple String outpu
ostream& operator<< (ostream &os, const String &st)
{
  os << st.str;
  return os;
}

// quick and dirty String input
istream& operator>> (istream &is, String &st)
{
  char temp[String::CINLIM];
  is.get(temp, String::CINLIM);
  if(is)
    st = temp;
  while(is && is.get() != '\n')
    continue;
  return is;
}
// 示例: sayings1.cpp
#include <iostream>
#include "string1.h"

const int ArSize = 10;
const int MaxLen = 81;

int main(int argc, char* argv[])
{
  using std::cout;
  using std::cin;
  using std::endl;

  String name;
  cout<<"Hi, what's your name?\n>> ";
  cin>>name;

  cout<<name<<", please enter up to "<<ArSize<<" short sayings <empty line to quit>:\n";

  String sayings[ArSize];  // array of objects
  char temp[MaxLen];       // temporary string storage
  int i;
  for(i = 0; i < ArSize; i++) {
    cout<<i+1<<": ";
    cin.get(temp, MaxLen);
    while(cin && cin.get() != '\n')
      continue;
    if(!cin || temp[0] == '\0') // empty line
      break;                    // i not incremented
    else
      sayings[i] = temp;        // overloaded assignment
  }

  int total = i;                // total # of lines read
  cout<<"Here are your saying:\n";
  for(i = 0; i < total; i++)
    cout<<sayings[i][0]<<": "<<sayings[i]<<endl;

  int shortest = 0;
  int first = 0;
  for(i = 1; i< total; i++) {
    if(sayings[i].length() < sayings[shortest].length())
      shortest = i;
    if(sayings[i] < sayings[first])
      first = i;
  }
  cout<<"Shortest saying:\n"<<sayings[shortest]<<endl;
  cout<<"First alphabetically:\n"<<sayings[first]<<endl;
  cout<<"This program used "<<String::HowMany()<<" String objects. Bye!\n";

  return 0;
}

编译: g++ -Wall -o sayings  sayings1.cpp string1.cpp

最终执行结果如下图:

猜你喜欢

转载自blog.csdn.net/wangell/article/details/38174699