1. 程式人生 > >建構函式,拷貝建構函式,解構函式,運算子過載

建構函式,拷貝建構函式,解構函式,運算子過載

一、建構函式

1、概念

 建構函式是一種特殊的成員函式。名字與類名相同,建立類型別物件時,由編譯器自動呼叫,在物件的宣告週期內只調用一次,以保證每個資料成員都有一個合適的初始值。

 

2、建構函式的特性

(1)函式名與類名相同;

(2)沒有返回值;

(3)有初始化列表;

(4)新物件被建立,由編譯器自動呼叫,且在物件的生命週期內僅呼叫一次;

(5)建構函式可以過載,實參決定了呼叫哪個建構函式。

(6)如果沒有顯示定義時,編譯器會提供一個預設的建構函式。

(7)無參建構函式和帶有預設值得建構函式都認為是預設建構函式,並且建構函式只能有一個。

(8)建構函式不能用const來修飾。

3、初始化列表

初始化列表:以一個冒號開始,接著是一個以逗號分隔得資料成員,每個資料成員後面跟一個放在圓括號中的初始化。

 

4、初始化列表

1、每個成員在初始化列表中只能出現一次;

2、初始化列表僅用於初始化資料成員,並不指定這些資料成員的初始化順序。資料成員在類中定義順序就是在列表中的初始化順序。

3、儘量避免使用成員初始化成員,成員的初始化順尋最好和成員的定義順序保持一致。

4、類中包含以下成員必須放在初始化列表中初始化:

   1) 引用資料成員;

   2const資料成員

   3) 類型別成員(該類美喲預設的建構函式)

5、預設建構函式

類如果沒有顯示定義建構函式時,編譯器會合成一個預設的建構函式,該建構函式中什麼工作都不做。只要顯示定義了,即使該建構函式什麼也不做,編譯器也不會為該類合成預設的建構函式。編譯器生成的預設建構函式使用與變數初始化相同的規則來初始化成員。內建和複合型別的成員如指標、陣列,只對定義在全域性作用域中的物件初始化,當物件定義在區域性作用域時,內建和符合型別的成員不進行初始化。在某些情況下,預設建構函式是由編譯器隱式使用的。

建構函式作用:

(1)、構建物件

(2)、初始化物件

(3)、型別轉換

預設建構函式一定會生成的條件:假設有A類和B類,若B類裡面包含了用A類定義的物件,A類裡面有顯示定義的建構函式,B類裡面沒有顯示定義的建構函式。編譯器則會在B類裡面合成一個預設的建構函式用來呼叫A類裡面顯示定義的建構函式。

下面的例子可以看出編譯器不會合成預設的建構函式

 

當滿足上面給出的條件的時候編譯器則一定會預設的建構函式

  

6、建構函式的過載

在一個類中可以定義多個建構函式,以便為物件提供不同的初始化的方法,供使用者選用。這些建構函式具有相同的名字,而引數的個數或引數的型別不相同,這稱為建構函式的過載。

通過下面的例子可以瞭解怎樣應用建構函式的過載

例:定義一個時間類,在時間類中定義兩個建構函式,其中一個無參,一個有參

編寫程式:

 

7、帶有預設引數的建構函式

建構函式中引數的值既可以通過實參傳遞,也可以指定為某些預設值,即如果使用者不指定實參值,編譯系統就使形參的值為預設值。

編寫程式:

 

注意:無參建構函式和帶有預設值得建構函式都認為是預設建構函式,並且建構函式只能有一個。

二、拷貝建構函式

1、概念

只有單個形參,而且該形參是對本類型別物件的引用(常用const修飾),這樣的建構函式稱為拷貝建構函式。拷貝建構函式是特殊的建構函式,建立物件時使用已存在的同類物件來進行初始化,由編譯器自動呼叫。

 

2、特徵

(1)、它是建構函式的過載。

(2)、它的引數必須使用同類型物件的引用傳遞

(3)、如果沒有顯示定義,系統會自動合成一個預設的拷貝建構函式。預設的拷貝建構函式會依次拷貝類的資料成員完成初始化。

3、使用場景

(1)物件例項化物件

     Date d1(1900,1,1);

     Date d2(d1);

(2)傳值方式作為函式的引數

     Void FunTest(const Date date)

     {}

(3)傳值方式作為函式的返回值

     Date FunTest()

     {

         Date date;

         return date;

     }

三、解構函式

1、概念

與建構函式功能函式相反,在物件別銷燬時,由編譯器自動呼叫,完成類的一些資源清理和汕尾工作。

 

2、特徵

(1)解構函式在類名(即建構函式名)前加上字元~

(2)解構函式無引數無返回值。

(3)一個類有且只有一個解構函式。若無顯示定義,系統會自動生成預設的解構函式。

(4)物件生命週期結束時,c++編譯系統自動呼叫解構函式。

(5)解構函式本身並不是刪除物件,而是做一些資源的清理工作。

3、程式執行解構函式的幾種情況

(1)如果在一個函式中定義了一個物件,當這個函式被呼叫結束時,物件應該釋放,在物件釋放前自動執行解構函式。

(2)靜態區域性物件在函式呼叫結束時物件並不釋放,因此也不呼叫解構函式。只在main函式結束或呼叫exit函式結束程式時,才呼叫static區域性物件的解構函式。

(3)如果定義了一個全域性的物件,則在程式的流程離開其作用域時,呼叫該全域性的物件的解構函式。

(4)如果用new運算子動態地建立了一個物件,當用delete運算子釋放該物件時,先呼叫該物件的解構函式。

4、注意

解構函式的作用並不是刪除物件,而是在撤銷物件佔用的記憶體之前完成一些清理工作,使這部分記憶體可以被程式分配給新物件使用。程式設計者要事先設計好解構函式,已完成所需的功能,只要物件的生命週期結束,程式就自動執行解構函式來完成這些工作。

由於解構函式沒有引數,因此它不能被過載。一個類可以有多個建構函式但是隻能有一個解構函式。

四、運算子的過載

1、為什麼要對運算子過載

例:通過函式來用+”號實現複數相加(沒有用運算子過載)

 編寫程式:

 

執行結果:

 

從上面的程式可以看出,雖然這種方法可以實現兩個複數的加法,但是這種呼叫方式不直觀、太繁瑣,使人感到很不方便。人們自然會想到,能否也和整數的加法運算一樣,直接用加號+”來實現複數運算,如:c3=c1+c2;編譯器就會自動完成c1c2兩個複數相加的運算。如果能做到,就為物件的運算提供很大的方便。這就需要對運算進行過載。

2、對運算子過載的方法

運算子過載的方法時定義一個過載運算子的函式,是指定的運算子不僅能實現原有的功能,而且能實現相應的功能。也就是說,運算子過載是通過定義函式實現的。運算子的過載實質上是函式的過載。

過載運算子的函式一般格式如下:

函式型別  operator運算子名稱(引數列表)

{對運算子的過載處理}

例如,想將+”用於Complex類(複數)的加法運算,函式的原型可以是這樣的:

   Complex operator +(Complex& c2);

在上面的格式中,operator是關鍵字,是專門用於定義過載運算子的函式的,運算子名稱就是C++已有的運算子。注意:函式名是由operator和運算子組成的。上面的“operator+”就是函式名,意思是“對運算子+過載的函式”。

例:改寫上面的例題,對運算子+”實行過載,使之能用於兩個複數相加

編寫程式:

 

3、過載運算子的規則

(1)C++不允許使用者自己定義新的運算子,只能對已有的C++運算子進行過載。

(2)C++允許過載的運算子。

雙目算術運算子

+、—、*/%

關係運算符

==!=<><=>=

邏輯運算子

||&&!

單目運算子

+()、—()*(指標)&(取地址)

自增自減運算子

++、——

位運算子

|&~<<>>

賦值運算子

=+=*=\=、^=、<<=、>>

空間申請與釋放

newdeletenew[]delete[]

其他運算子

()->->*,,(逗號),[](下標)

不能過載的運算子只有五個:

.  (成員訪問運算子)

*  (成員指標訪問運算子)

::(域運算子)

sizeof(長度運算子)

?:(條件運算子)

前兩個運算子不能過載是為了保證訪問成員的功能不能被改變,域運算子和sizeof運算子的運算物件是型別而不是變數或一般表示式,不具備過載的特性。

(3)過載不能改變運算子運算物件(即運算元)的個數。如關係運算符>”等是雙目運算子,過載後仍為雙目運算子,需要兩個引數。

(4)過載不能改變運算子的優先級別。

(5)過載不能改變運算子的結合性。

(6)過載運算子的函式不能有預設的引數,否則就改變了運算子引數的個數,與前面第三點矛盾。

(7)過載運算子必須和使用者定義的自定義型別的物件一起使用,其引數至少應有一個是類物件(或者類的引用)。

(8)用於類物件的運算子一般必須過載,但有兩個例外,運算子=”和“&”不用使用者過載。

① 賦值運算子=”可以用於每一個類的物件,可以利用它在同類物件之間相互賦值。

② 地址運算子&”也不必過載,它能返回類物件在記憶體中的起始地址。

(9)從理論上說,可以將一個運算子過載為任意的操作。但是應該使過載運算子的功能類似於運算子作用於標準型別資料時所實現的功能。

4、過載流插入運算子和流提取運算子

使用者定義的型別的資料,是不能直接用<<”和“>>”輸出和輸入的。如果想用他們的輸出和輸入自己宣告的型別的資料,必須對它們進行過載。

<<”和“>>”過載的函式形式如下:

Istream & operator>>(istream&,自定義型別&)

ostream & operator<<(ostream&,自定義型別&)

只能將過載>>”和“<<”的函式作為友元函式,而不能將它們定義為成員函式。

(1)過載流插入運算子<<

例:編寫程式

classComplex

{

public:

Complex()

{

_real = 0;

_imag = 0;

}

Complex(doublereal,doubleimag)

{

_real = real;

_imag = imag;

}

Complex& operator+ (Complex&complex)

{

complex._real += _real;

complex._imag += _imag;

returncomplex;

}

friendostream& operator<<(ostream& _cout,Complex& complex);

private:

double _real;

double _imag;

};

ostream& operator<<(ostream&_cout,Complex&complex)

{

_cout <<"(" <<complex._real <<"+" <<complex

相關推薦

C++在單繼承、多繼承、虛繼承時建構函式、複製建構函式、賦值操作符、函式的執行順序和執行內容

一、本文目的與說明     1. 本文目的:理清在各種繼承時,建構函式、複製建構函式、賦值操作符、解構函式的執行順序和執行內容。     2. 說明:雖然複製建構函式屬於建構函式的一種,有共同的地方,但是也具有一定的特殊性,所以在總結它的性質時將它單獨列出來了。  

27.能否在建構函式中丟擲異常?函式呢?

首先,我們要明確一點!一個函式執行的過程中,如果丟擲異常,會導致函式提前終止! 在C++建構函式中,既需要分配記憶體,又需要丟擲異常時要特別注意防止記憶體洩露的情況發生。因為在建構函式中丟擲異常,在概念上將被視為該物件沒有被成功構造,因此當前物件的解構函式就不會被呼叫。同時

C++中基類的函式為什麼要用virtual虛函式【轉】

(轉自:https://blog.csdn.net/iicy266/article/details/11906457) 知識背景          要弄明白這個問題,首先要了解下C++中的動態繫結。&n

C++中基類的函式為什麼要用virtual虛函式

知識背景          要弄明白這個問題,首先要了解下C++中的動態繫結。  正題          直接的講,C++中基類採用virtual虛解構函式是為了防止記憶體洩漏。具體地說,如果派生類中申請了記憶體空間,並在其解構函式中對這些記憶體空間進行釋放

[收集]c++抽象類、純虛擬函式以及巧用純虛函式實現介面類

在Java、C#中有關鍵詞abstract指明抽象函式、抽象類,但是在C++中沒有這個關鍵詞,很顯然,在C++也會需要只需要在基類宣告某函式的情況,而不需要寫具體的實現,那C++中是如何實現這一功能的,答案是純虛擬函式。 含有純虛擬函式的類是抽象類,不能生成物件,只能派生。

建構函式拷貝建構函式函式賦值函式

例一: class CGoods {     //行為,成員方法 public:     CGoods(char *name = NULL, int amount = 0, double price = 0.0) //建構函式 &nbs

C++類中的一些細節(過載、重寫、覆蓋、隱藏建構函式函式拷貝建構函式、賦值函式在繼承時的一些問題)

1 函式的過載、重寫(重定義)、函式覆蓋及隱藏 其實函式過載與函式重寫、函式覆蓋和函式隱藏不是一個層面上的概念。前者是同一個類內,或者同一個函式作用域內,同名不同引數列表的函式之間的關係。而後三者是基類和派生類函式不同情況下的關係。 1.1 函式過載

C++中建構函式拷貝建構函式函式

C++中預設建構函式就是沒有形參的建構函式。準確的說法,按照《C++ Primer》中定義:只要定義一個物件時沒有提供初始化式,就是用預設建構函式。為所有 的形參提供預設實參的建構函式也定義了預設建構函式。 合成的預設建構函式,即編譯器自動生成的預設建構函式。《C++ Pr

c++建構函式拷貝建構函式函式賦值運算子過載

建構函式:        是一個特殊的成員函式,名字與類名相同,建立類型別物件時,由編譯器自動呼叫,在物件的生命週期內只且只調用一次,以保證每個資料成員都有一個合適的初始值。 <strong&g

廣義表的C++實現(包含建構函式拷貝建構函式函式獲取表頭表尾獲取直接後繼等操作)

資料結構是資料在系統中的物理儲存結構,自己編寫資料結構可以對某種資料結構的物理和邏輯結構有更深的瞭解。 一、廣義表作為一種資料結構有以下的特點: 1. 廣義表是遞迴的; 2. 廣義表的元素可以使廣義表,也可以是值; 3. 廣義表是有序的; 4. 廣義表是有長度有深度的。 二

c++類詳:訪問許可權建構函式拷貝建構函式函式

類的定義 類可以看做是一種資料型別,類這種資料型別是一個包含成員變數和成員函式的集合。類的成員變數和普通變數一樣,也有資料型別和名稱,佔用固定長度的記憶體。但是,在定義類的時候不能對成員變數賦值,因為類只是一種資料型別或者說是一種模板,本身不佔用記憶體空間,而變數的值則需要

建構函式拷貝建構函式函式運算子過載

一、建構函式 1、概念  建構函式是一種特殊的成員函式。名字與類名相同,建立類型別物件時,由編譯器自動呼叫,在物件的宣告週期內只調用一次,以保證每個資料成員都有一個合適的初始值。   2、建

C++之建構函式函式拷貝建構函式

一、定義    建構函式:是在一個定義在類裡面的函式,它的作用是在你建立這個類的物件時被自動呼叫。                    如果你自己定義了則呼叫自己定義的,否則呼叫預設的。    解構函式:是一個在類裡面定義的函式,它的作用是在你的類物件死亡時被呼叫刪除這個類

C++何時呼叫建構函式何時呼叫函式

前言:   最近自考C++刷題的時候快被建構函式和解構函式搞得瘋掉了,現在特意寫一篇部落格來記錄自己的收穫! 在我們建立新的物件的時候,都要執行某一個類中的建構函式,而當建構函式中分配了資源之後,當我們銷燬一個物件的時候需要一個相應的操作將這些資源釋放出去,這就需要解

設計模式中的單例模式的程式碼為什麼函式會多次被呼叫建構函式只調用一次

單例模式 package com.seven.exercise.testEception; /**  * 單例模式,餓漢式  * @author Seven  *  */ public class SingleDemoHunger {   &nb

c++實現String類(建構函式函式複製建構函式各類運算子過載函式的編寫)

編寫類 String 的建構函式,解構函式,複製建構函式  需要過載下面的運算子: 1、<、>、==和!=比較運算子 2、+=連線運算子和賦值運算子 3、<<輸出運算子和>>輸入運算子 String.h #ifndef _STRING

C++第十週【任務2】定義一個名為CPerson的類有以下私有成員:姓名、身份證號、性別和年齡成員函式建構函式函式、輸出資訊的函式

/* (程式頭部註釋開始) * 程式的版權和版本宣告部分 * Copyright (c) 2011, 煙臺大學計算機學院學生 * All rights reserved. * 檔名稱: C++第十週【任務2】 * 作

C++ 建構函式函式中能否呼叫虛擬函式

牛客網 ------------------- ------------------- ------------------- 設計模式 ------------------- -------------------

C++基礎知識(八)---函式返回值(返回值返回指標返回物件返回引用)---引用---複製建構函式拷貝建構函式

一、函式返回值   1.返回值: int test () { int a=1; return a; }   返回值時最簡單的方式,它的操作主要在棧上,變數a在函式結束後會刪除,為了返回a的值,系統會在內部建立一個臨時變數儲存a的值,以返回給呼叫該函式的表示式,呼叫結束後變數便

c++的建構函式極其呼叫(無參建構函式有參建構函式拷貝建構函式

1.c++編譯器會自動呼叫建構函式//建構函式(與類名相同) //解構函式:沒有引數也沒有任何返回型別,被自動呼叫 #include<iostream> using namespace std; class Test { public: Test();//無參建