日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

C++中的五种构造函数

發布時間:2023/12/16 c/c++ 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++中的五种构造函数 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

這里寫目錄標題

  • 默認構造函數
    • 何時生成默認的構造函數
  • 普通構造函數
  • 拷貝構造函數
    • 何時生成默認的拷貝構造函數
    • 拷貝構造函數調用的時機
  • 轉換構造函數
  • 移動構造函數

C++中的構造函數可以分為5類:默認構造函數、普通構造函數、拷貝構造函數、轉換構造函數、移動構造函數。

默認構造函數

未提供顯式初始值時,用來創建對象的構造函數。以Student類為例,默認構造函數的原型為

Student();//沒有參數 Student(int num=0;int age=0);//所有參數均有默認值

何時生成默認的構造函數

當一個類沒有構造函數時,如果滿足以下四個條件其中之一,則編譯器會為該類自動生成一個默認的構造函數:

  • 該類含有一個類類型(非內置類型)的成員變量,且該類型含有默認構造函數。
  • 該類繼承自含有默認構造函數的基類。
  • 該類繼承或聲明了虛函數。
  • 該類含有虛基類。
  • 普通構造函數

    C++用于構建類的新對象時需要調用的函數

    Student(int num,int age);//有參數

    拷貝構造函數

    何時生成默認的拷貝構造函數

    當一個類沒有拷貝構造函數時,如果滿足以下四個條件其中之一,則編譯器會為該類自動生成一個默認的拷貝構造函數:

  • 該類含有一個類類型(非內置類型)的成員變量,且該類型含有拷貝構造函數。
  • 該類繼承自含有拷貝構造函數的基類。
  • 該類繼承或聲明了虛函數。
  • 該類含有虛基類。
  • 需要注意的是,默認的拷貝構造函數實現的是淺拷貝

    拷貝構造函數調用的時機

    拷貝構造函數在以下三種情況下會被調用

    1).當用一個對象去初始化同類的另一個對象時,會引發復制構造函數被調用。例如,下面的兩條語句都會引發復制構造函數的調用,用以初始化 c2。

    Complex c2(c1); Complex c2 = c1;

    這兩條語句是等價的。

    注意,第二條語句是初始化語句,不是賦值語句。賦值語句的等號左邊是一個早已有定義的變量,賦值語句不會引發復制構造函數的調用。例如:

    Complex c1, c2; c1=c2;

    這條語句不會引發復制構造函數的調用,因為 c1 早已生成,已經初始化過了。

    2).如果函數 F 的參數是類 A 的對象,那么當 F 被調用時,類 A 的復制構造函數將被調用。換句話說,作為形參的類A的對象,是用復制構造函數初始化的,而且調用復制構造函數時的參數,就是調用函數時所給的實參。

    #include<iostream> using namespace std; class A{ public:A(){};A(A & a){cout<<"Copy constructor called"<<endl;} }; void Func(A a){ } int main(){A a;Func(a);return 0; }

    程序的輸出結果為:

    Copy constructor called

    這是因為 Func 函數的形參 a 在初始化時調用了復制構造函數。

    前面說過,函數的形參的值等于函數調用時對應的實參,現在可以知道這不一定是正確的。如果形參是一個對象,那么形參的值是否等于實參,取決于該對象所屬的類的復制構造函數是如何實現的。例如上面的例子,Func 函數的形參 a 的值在進入函數時是隨機的,未必等于實參,因為復制構造函數沒有做復制的工作。

    以對象作為函數的形參,在函數被調用時,生成的形參要用復制構造函數初始化,這會帶來時間上的開銷。如果用對象的引用而不是對象作為形參,就沒有這個問題了。但是以引用作為形參有一定的風險,因為這種情況下如果形參的值發生改變,實參的值也會跟著改變。

    如果要確保實參的值不會改變,又希望避免復制構造函數帶來的開銷,解決辦法就是將形參聲明為對象的 const 引用。例如:

    void Function(const Complex & c) {... }

    3). 如果函數的返冋值是類 A 的對象,則函數返冋時,類 A 的復制構造函數被調用。換言之,作為函數返回值的對象是用復制構造函數初始化 的,而調用復制構造函數時的實參,就是 return 語句所返回的對象。例如下面的程序:

    #include<iostream> using namespace std; class A { public:int v;A(int n) { v = n; };A(const A & a) {v = a.v;cout << "Copy constructor called" << endl;} }; A Func() {A a(4);return a; } int main() {cout << Func().v << endl;return 0; }

    程序的輸出結果是:

    Copy constructor called 4

    轉換構造函數

    一個構造函數接收一個不同于其類類型的形參,可以視為將其形參轉換成類的一個對象。像這樣的構造函數稱為轉換構造函數。在 C++ string 類中可以找到使用轉換構造函數的實用示例。string 類提供一個將 C 字符串轉換為 string 的轉換構造函數

    class string {//僅顯示轉換構造函數public:string(char *);//形參時其他類型變量,且只有一個形參 };

    移動構造函數

    所謂移動語義,指的就是以移動而非深拷貝的方式初始化含有指針成員的類對象。簡單的理解,移動語義指的就是將其他對象(通常是臨時對象)擁有的內存資源“移為已用”。事實上,對于程序執行過程中產生的臨時對象,往往只用于傳遞數據(沒有其它的用處),并且會很快會被銷毀。因此在使用臨時對象初始化新對象時,我們可以將其包含的指針成員指向的內存資源直接移給新對象所有,無需再新拷貝一份,這大大提高了初始化的執行效率。

    #include <cstring>using namespace std;class Str{public:char *str;Str(Str &&s)//移動構造函數{}~Str(){} };

    總結

    以上是生活随笔為你收集整理的C++中的五种构造函数的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。