C++面向物件常用的四個函式
C++是面向物件的語言,和C語言面向過程有不同,C++更針對於一類事物的本質,它的使用就和C語言有所不同。下面是使用面向過程的思想經常使用的四個函式,下面的四個函式將會伴隨我們C++的整個生涯。
①建構函式,②拷貝建構函式,③過載=運算子函式,④解構函式。
我們使用一個簡單的Person類來講解。
class Person { private: char *_name; int _age; public: Person()//建構函式 { _name = NULL; _age = 0; } Person(char *name, int age);//有引數的建構函式 Person(const Person & src);//拷貝建構函式 Person& operator=(const Person &src);//過載 ~Person();//解構函式 };
(1)建構函式
①如果不自己實現建構函式,編譯期會自動生成一個建構函式,但他什麼也不做,如果自己實現構造函數了,編譯期就不會自動生成構造方法。
②自己實現建構函式,與類同名,沒有返回值,引數列表可以為空,第一個就是引數列表為空的建構函式,第二個就是帶有引數的建構函式
無引數的建構函式已經實現,我們實現一下帶引數的建構函式。
Person::Person(char *name, int age) { _name = new char[strlen(name)+1]; strcpy_s(_name, strlen(name)+1, name); _age = age; }
(2)拷貝建構函式
①用一個已經存在的物件構造一個正在生成的物件,這個過程中所自動呼叫的函式就是拷貝建構函式,拷貝建構函式也算是建構函式,但是他更特殊一點。
②與類同名,引數列表必選傳一個物件的引用。為什麼要傳引用呢,因為實參傳形參為初始化的過程,會出現拷貝構造,而拷貝構造又會重新初始化,這就會出現死遞迴的情況。
③防止淺拷貝:如果函式內對開闢的記憶體只進行簡單的指標賦值,則會出現淺拷貝(例如:兩個Person物件的name都指向同一段記憶體,一個物件改名,另一個物件也會改名),我們需要預防淺拷貝,所以需要重新申請記憶體進行深拷貝。
它的實現如下:
Person::Person(const Person & src) { //預防淺拷貝 _name = new char[strlen(src._name)+1]; strcpy_s(_name, strlen(src._name)+1, src._name); _age = src._age; }
(3) 過載=運算子
過載=運算子的主體實現類似拷貝構造,但是它有幾個需要特別注意的地方。
①防止記憶體洩漏:在進行=運算時要先把原來的記憶體釋放掉。
②防止自賦值:如果自己給自己賦值,我們已經把自己的記憶體釋放掉了,怎麼尋找需要拷貝的記憶體。
③防止淺拷貝
Person& Person::operator=(const Person &src)
{
if(this == &src)
{
return *this;
}
if(NULL != _name)
{
delete []_name;
}
_name = new char[strlen(src._name)+1];
strcpy_s(_name, strlen(src._name)+1, src._name);
_age = src._age;
return *this;
}
(4)解構函式
①解構函式在類的名字前面加~,也是沒有引數列表。
②解構函式是物件生存期滿後預設呼叫的成員函式。
③它的主要作用就是防止記憶體洩漏。
Person::~Person()
{
if(_name != NULL)
{
delete[]_name;
}
}
其實整體看來前三個函式除了一些處理之外特別相似,但是他們使用的場景是不同的。