拷貝構造函數、析構函數以及賦值操作符=

//接口文件strvar.h

#ifndef STRINGVAR_H
#define STRINGVAR_H

#include <iostream>
using namespace std;
namespace sunyufeng
{
 class StringVar
 {
 public:
  StringVar(int size);
  StringVar();
  StringVar(const char a[]);
  StringVar(const StringVar& string_object);
  ~StringVar();
  int length() const;
  void input_line(istream& ins);
  void operator = (const StringVar& right_side);
  friend ostream& operator << (ostream& outs,const StringVar& the_string);
 private:
  char *value;
  int max_length;
 };//StringVar
}//sunyufeng

#endif

//實現文件 strvar.cpp

#include <iostream>
#include <cstdlib>
#include <cstddef>
#include <cstring>
#include "StringVar.h"
using namespace std;

namespace sunyufeng
{
 StringVar::StringVar(int size):max_length(size)
 {
  value = new char[max_length+1];
  value[0] = '/0';
 }

 StringVar::StringVar():max_length(100)
 {
  value = new char[max_length+1];
  value[0] = '/0';
 }

 StringVar::StringVar(const char a[]):max_length(strlen(a))
 {
  value = new char[max_length+1];
  strcpy(value,a);
 }

 StringVar::StringVar(const StringVar& string_object):max_length(string_object.length

())
 {
  value = new char[max_length+1];
  strcpy(value,string_object.value);
 }

 StringVar::~StringVar()
 {
  delete [] value;
 }

 int StringVar::length() const
 {
  return strlen(value);
 }

 void StringVar::input_line(istream& ins)
 {
  ins.getline(value,max_length+1);
 }

 void StringVar::operator = (const StringVar& right_side)
 {
  int new_length = strlen(right_side.value );
  if (new_length>max_length)
  {
   delete [] value;
   max_length = new_length;
   value = new char[max_length+1];
  }
  for(int i=0;i<new_length;i++)
   value[i] = right_side.value [i] ;
  value[new_length]='/0';
 }

 ostream& operator << (ostream& outs,const StringVar& the_string)
 {
  outs<<the_string.value;
  return outs;
 }

}//sunyufeng

//應用程序 main.cpp

#include <iostream>
#include "StringVar.h"

void conversation(int max_name_size);

int main()
{
 using namespace std;
 conversation(30);
 cout<<"end of demonstration."<<endl;

 return 0;
}

void conversation(int max_name_size)
{
 using namespace std;
 using namespace sunyufeng;
 StringVar your_name(max_name_size),our_name("Borg");

 cout<<"What is your name ?"<<endl;
 your_name.input_line (cin);
 cout<<"we are "<<our_name<<endl;
 cout<<"we will meet again "<<your_name<<endl;
}

 

析構函數是類的一個成員函數,它在類的對象超出作用域之後自動調用。例如,假定類類型的一個對象是

某函數的局部變量,那麼調用析構函數就是函數調用結束之前採取的最後一項行動。析構函數用於銷燬由

對象創建的任意的動態變量,將這些動態變量佔用的內存返還給堆區。析構函數還可以執行其他清理工作

。但將內存收回到堆區纔是析構函數的主要工作。

析構函數沒有參數,每個類只能有一個析構函數,而且析構函數不能重載。

拷貝構造函數是含有一個傳引用調用參數的構造函數,它具有與類相同的類型。這個參數必須是一個傳引

用調用參數;通常,參數是一個常量參數。只要某個函數返回類類型的一個值,就會自動調用那個類的拷

貝構造函數。如果類定義涉及到指針以及使用操作符new來動態分配內存,你需要包括一個拷貝構造函數

。不涉及指針或者動態分配內存的類則不需要拷貝構造函數。

Big Three
複製構造函數、=操作符以及析構函數統稱爲big three。如果你需要定義其中任何一個,就必須定義全

部三個。缺少任何一個,編譯器會幫你創建它,只是可能達不到你所預期的效果。所以,你有必要每次定

義他們。假如所有成員變量都具有與定義類型(比如int和double),那麼編譯器爲你生成的拷貝構造函

數和重載操作符=能夠很好的工作。然而,假如一個類中包含類或者指針成員變量,它們就有可能表現異

常。對於使用了指針和操作符new的任何類,最保險的做法就是定義你自己的拷貝構造函數、重載操作符=

以及析構函數。

賦值和初始化
C++對初始化和賦值進行了細緻的區分。初始化用拷貝構造函數來新建一個對象;賦值操作符獲得一個現

有對象,並對其進行修改,使其成爲與賦值操作符右側的對象完全相同的一個副本(準確的說,兩者除了

位置不同,其餘完全相同)。
 

發佈了10 篇原創文章 · 獲贊 0 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章