那曲檬骨新材料有限公司

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

C/C++之面向對象編程思想2

jf_78858299 ? 來源:小余的自習室 ? 作者:小余的自習室 ? 2023-03-30 15:14 ? 次閱讀

C++中的幾種特殊成員函數

構造函數

C++在編譯器會給我們默認創建一個缺省的構造方法: 如下代碼:

class Father {
public:
    string name = "father";
    int age = 45;
    void print() {
        cout << "name:" << name << " age:" << age << endl;
    }
};
class Son :public Father {
public:
    string sex = "male";
};

void extendsTest::mainTest()
{
    Son son;
    son.print();
};
運行結果:name:father age:45

可以看到雖然我們沒有明確聲明構造方法,但是依然可以調用無參構造方法。這就是因為 編譯器自動給我們創建了一個無參構造方法

如果類定義了自己的構造方法后(包括無參和有殘),編譯器就不會給我們創建了 ,看下面代碼:

class Father {
public:
    Father() {
        cout << "Father:" << name << endl;
    }
    string name = "father";
    int age = 45;
    void print() {
        cout << "name:" << name << " age:" << age << endl;
    }
};
class Son :public Father {
public:
    Son(){
        cout << "Son:" << name << endl;
    }
    string sex = "male";    
};

void extendsTest::mainTest()
{
    Son son;
    son.print();
};
打印結果:
Father:father
Son:father
name:father age:45

從上面代碼也可以看出C++編譯器會默認優先調用父類的構造方法,再調用子類的構造方法,

這點和java中是有區別的,java會從子類開始依次調用父類的構造方法,然后回溯子類的構造方法

所以為了保證對象的順利創建,需要保證父類的構造方法是有效的。 如下代碼:

class Father {
public:
    Father(string _name):name(_name){
        cout << "Father:" << name << endl;
    }
    string name = "father";
    int age = 45;
};

此時父類中創建了一個有參構造方法,前面說過,此時編譯器不會創建默認的無參構造方法,則需要保證在其子類中有初始化父類的操作:即調用父類有參構造方法。 如下代碼:

class Son :public Father {
public:
    Son(string name):Father(name) {
        cout << "Son:" << name << endl;
    }
    string sex = "male";
};

void extendsTest::mainTest()
{
    Son son1("myName");
};
結果:
Father:myName
Son:myName

析構函數

析構函數用來釋放當前對象使用到的內存空間,當對象跳出其作用域范圍后就會執行析構函數( 除非是有智能指針出現循環引用的情況,無法釋放,導致泄露 )。 C++中析構函數和構造函數相反,會 優先調用子類的析構函數再調用父類的析構函數 。 如下代碼:

class Father {
public:
    ~Father() {
        cout << "~Father"<< endl;
    }
    string name = "father";
    int age = 45;

};
class Son :public Father {
public:
    ~Son() {
        cout << "~Son" << endl;
    }   
    string sex = "male";    
};

void extendsTest::mainTest()
{
    Son son;
};
運行結果:
~Son
~Father

拷貝構造

C++中拷貝構造函數格式:

  • 格式1 :帶const參數 Complex(const Complex& c) { … } 表示以常量對象作為參數
  • 格式2 :不帶const參數 Complex(Complex& c) { … } 表示以非常量作為參數進行拷貝 如下代碼:
class Complex {
  public:
    double real, imag;
    Complex(double _real, double _imag):
        real(_real),imag(_imag)
    {
        cout << "real:" << real << " imag:" << imag << endl;
    }
    void print() {
        cout << "real:" << real << " imag:" << imag << endl;
    }
    Complex(Complex& c) {
        real = c.real+1; imag = c.imag+1;
    }
  };

void extendsTest::mainTest()
{
    Complex c1(1.0, 2.0);
    Complex c2(c1);
    c2.print();
};
打印結果:
real:1 imag:2
real:2 imag:3

拷貝構造函數和構造方法類似, C++編譯器會給我們提供默認的拷貝構造函數 。 將上面代碼的拷貝構造函數刪除后:

class Complex {
public:
    double real, imag;
    Complex(double _real, double _imag):
        real(_real),imag(_imag)
    {
        cout << "real:" << real << " imag:" << imag << endl;
    }
    void print() {
        cout << "real:" << real << " imag:" << imag << endl;
    }
};

void extendsTest::mainTest()
{
    Complex c1(1.0, 2.0);
    Complex c2(c1);
    c2.print();
};

依然可以執行拷貝構造,此時c2使用了默認拷貝構造函數進行賦值。

拷貝構造的幾種調用形式:

  • 1.當用一個對象去初始化同類的另一個對象時

    Complex c2(c1);
    Complex c2 = c1;
    

    這兩天語句是等價的。但是要 注意此時Complex c2 = c1是一個初始化語句,并非一個賦值語句。賦值語句是一個已經初始化后的變量 。 如下:

    Complex c1, c2; c1 = c2 ;
    c1=c2;
    

    賦值語句不會觸發拷貝構造

  • 2.當對象作為一個函數形參時,此時也會觸發對象的拷貝構造

    class Complex {
      public:
        double real, imag;
        Complex(double _real, double _imag):
            real(_real),imag(_imag)
        {
            cout << "real:" << real << " imag:" << imag << endl;
        }
        Complex(Complex& c) {
            real = c.real+1; imag = c.imag+1;
            cout << "complex copy" << endl;
        }
      };
    
    void func(Complex c) {
        cout << "real:" << c.real << " imag:" << c.imag << endl;
    
    }
    
    void extendsTest::mainTest()
    {   
        Complex c(1.0,2.0);
        func(c);
    };
    
    運行結果:
    real:1 imag:2
    complex copy
    real:2 imag:3
    

    可以看到運行結果觸發了Complex的拷貝構造 以對象作為函數的形參,在函數被調用時,生成的形參要用復制構造函數初始化,這會帶來時間上的開銷。 如果用對象的引用而不是對象作為形參,就沒有這個問題了

    void func(Complex& c) {
        cout << "real:" << c.real << " imag:" << c.imag << endl;
    }
    

    但是以引用作為形參有一定的風險,因為這種情況下如果形參的值發生改變,實參的值也會跟著改變。 最好的方法就是將函數形參聲明為const類型的引用

    void func(const Complex& c) {
        cout << "real:" << c.real << " imag:" << c.imag << endl;
    }
    
  • 3.對象作為函數返回值返回時,也會觸發拷貝構造。

    Complex func() {
        Complex c(1.0, 2.0);
        return c;
      }
      void extendsTest::mainTest()
      { 
        cout << func().real << endl;
      };
    
    結果:
    real:1 imag:2
    complex copy
    2
    

    可以看到此時func函數中的return c處會觸發一次拷貝構造,并將拷貝后的對象返回。 這點通過函數hack過程也可以看出來:此處call方法執行的是拷貝構造方法

    圖片

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • JAVA
    +關注

    關注

    19

    文章

    2975

    瀏覽量

    105154
  • C++
    C++
    +關注

    關注

    22

    文章

    2114

    瀏覽量

    73859
  • 面向對象編程

    關注

    0

    文章

    22

    瀏覽量

    1841
收藏 人收藏

    評論

    相關推薦

    Labview 之面向對象編程。 里面有個例子 和視頻教程地址

    Labview 之面向對象編程。 里面有個例子 和視頻教程地址Labview 之面向對象編程
    發表于 12-29 10:16

    C++ 面向對象多線程編程下載

    C++ 面向對象多線程編程下載
    發表于 04-08 02:14 ?70次下載

    C++面向對象多線程編程 (pdf電子版)

    C++面向對象多線程編程共分13章,全面講解構建多線程架構與增量多線程編程技術。第1章介紹了
    發表于 09-25 09:39 ?0次下載

    C++課件

     C++面向對象程序設計 面向對象思想的由來面向
    發表于 04-10 13:41 ?0次下載

    Visual C++面向對象與可視化程序設計習題解析與編程

    Visual C++面向對象與可視化程序設計習題解析與編程實例從最基本的概念出發,詳細地講述了使用Visual C++進行
    發表于 07-12 15:16 ?0次下載
    Visual <b class='flag-5'>C++</b><b class='flag-5'>面向</b><b class='flag-5'>對象</b>與可視化程序設計習題解析與<b class='flag-5'>編程</b>實

    C++編程思想

    C++編程思想,很好的資料,大家下載看看吧!夠20字了吧,哈哈哈!
    發表于 11-17 11:38 ?0次下載

    面向對象的程序設計(C++

    面向對象的程序設計(C++).面向對象的基本思想 C++
    發表于 03-22 14:40 ?0次下載

    C#入門教程之面向對象編程簡介的詳細資料概述

    本文檔的主要內容詳細介紹的是C#入門教程之面向對象編程簡介的詳細資料概述主要學習的目標是1.面向對象
    發表于 12-05 11:54 ?35次下載
    <b class='flag-5'>C</b>#入門教程<b class='flag-5'>之面向</b><b class='flag-5'>對象</b><b class='flag-5'>編程</b>簡介的詳細資料概述

    C++語言和面向對象程序設計教程

    章至第11章介紹符合C++國際標準的C++面向對象程序設計思想和方法;第12章和第13章分別介紹面向
    發表于 03-02 08:00 ?6次下載

    STM32 C++編程系列二:STM32 C++代碼封裝初探

    一、STM32與面向對象編程上一章中提到了,C++的核心之一就在于面向對象
    發表于 12-08 11:06 ?13次下載
    STM32 <b class='flag-5'>C++</b><b class='flag-5'>編程</b>系列二:STM32 <b class='flag-5'>C++</b>代碼封裝初探

    嵌入式C語言面向對象編程應用及優勢

    既然面向對象是一種編程思想,而編程語言只是一種工具,那么,思想與工具之間就不存在一種強耦合的關系
    發表于 11-10 12:00 ?1840次閱讀
    嵌入式<b class='flag-5'>C</b>語言<b class='flag-5'>面向</b><b class='flag-5'>對象</b><b class='flag-5'>編程</b>應用及優勢

    C語言是怎么面向對象編程

    在嵌入式開發中,C/C++語言是使用最普及的,在C++11版本之前,它們的語法是比較相似的,只不過C++提供了面向
    的頭像 發表于 02-14 13:57 ?1739次閱讀
    <b class='flag-5'>C</b>語言是怎么<b class='flag-5'>面向</b><b class='flag-5'>對象</b><b class='flag-5'>編程</b>

    C/C++之面向對象編程思想1

    C++作為一門在C和Java之間的語言,其既可以使用C語言中的高效指針,又繼承了Java中的面向對象編程
    的頭像 發表于 03-30 15:14 ?682次閱讀
    <b class='flag-5'>C</b>/<b class='flag-5'>C++</b><b class='flag-5'>之面向</b><b class='flag-5'>對象</b><b class='flag-5'>編程</b><b class='flag-5'>思想</b>1

    C/C++之面向對象編程思想3

    C++作為一門在C和Java之間的語言,其既可以使用C語言中的高效指針,又繼承了Java中的面向對象編程
    的頭像 發表于 03-30 15:16 ?609次閱讀
    <b class='flag-5'>C</b>/<b class='flag-5'>C++</b><b class='flag-5'>之面向</b><b class='flag-5'>對象</b><b class='flag-5'>編程</b><b class='flag-5'>思想</b>3

    淺談C語言面向對象編程思想

    C語言是一種面向過程的語言,但是也可以用結構體和函數指針來模擬面向對象的特性,比如封裝、繼承和多態。
    發表于 11-02 12:27 ?1183次閱讀
    漯河市| 博发百家乐官网的玩法技巧和规则 | 百家乐官网园百利宫娱乐城信誉好...| 做生意容易成功的八字| 大发888国际娱乐net| 网上百家乐官网合法吗| 皇冠百家乐客户端皇冠| 大发娱乐| 澳门百家乐官网路单| 威尼斯人娱乐场官网| 赌场百家乐官网技巧| 百家乐赌博机有鬼吗| tt线上娱乐城| 百家乐怎么才会赢| 博彩排名| 博九百家乐官网的玩法技巧和规则| 老虎机定位器| 百家乐官网路子分| 水果老虎机的程序| 百家乐官网怎么押钱| 百家乐b28博你| 阿拉善右旗| 广州百家乐娱乐场| 江阴市| 澳门百家乐网上赌博| 网络百家乐官网的陷阱| 百家乐网上真钱娱乐场| 大发888下载| 百家乐官网视| 澳门玩大小| 澳门百家乐奥秘| 欧凯百家乐的玩法技巧和规则| 百家乐官网哪家信誉好| 黄金百家乐的玩法技巧和规则| 网上百家乐官网有假的吗| 涂山百家乐的玩法技巧和规则 | 太阳城百家乐官网坡解| 闲和庄百家乐的玩法技巧和规则| 惠来县| 百家乐解密软件| 金花百家乐官网娱乐城|