//接口文件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++對初始化和賦值進行了細緻的區分。初始化用拷貝構造函數來新建一個對象;賦值操作符獲得一個現
有對象,並對其進行修改,使其成爲與賦值操作符右側的對象完全相同的一個副本(準確的說,兩者除了
位置不同,其餘完全相同)。