RM新时代网站-首页

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

C/C++之面向?qū)ο缶幊趟枷?

jf_78858299 ? 來(lái)源:小余的自習(xí)室 ? 作者:小余的自習(xí)室 ? 2023-03-30 15:14 ? 次閱讀

C++中的幾種特殊成員函數(shù)

構(gòu)造函數(shù)

C++在編譯器會(huì)給我們默認(rèn)創(chuàng)建一個(gè)缺省的構(gòu)造方法: 如下代碼:

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();
};
運(yùn)行結(jié)果:name:father age:45

可以看到雖然我們沒(méi)有明確聲明構(gòu)造方法,但是依然可以調(diào)用無(wú)參構(gòu)造方法。這就是因?yàn)?編譯器自動(dòng)給我們創(chuàng)建了一個(gè)無(wú)參構(gòu)造方法 、

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

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();
};
打印結(jié)果:
Father:father
Son:father
name:father age:45

從上面代碼也可以看出C++編譯器會(huì)默認(rèn)優(yōu)先調(diào)用父類的構(gòu)造方法,再調(diào)用子類的構(gòu)造方法,

這點(diǎn)和java中是有區(qū)別的,java會(huì)從子類開(kāi)始依次調(diào)用父類的構(gòu)造方法,然后回溯子類的構(gòu)造方法

所以為了保證對(duì)象的順利創(chuàng)建,需要保證父類的構(gòu)造方法是有效的。 如下代碼:

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

此時(shí)父類中創(chuàng)建了一個(gè)有參構(gòu)造方法,前面說(shuō)過(guò),此時(shí)編譯器不會(huì)創(chuàng)建默認(rèn)的無(wú)參構(gòu)造方法,則需要保證在其子類中有初始化父類的操作:即調(diào)用父類有參構(gòu)造方法。 如下代碼:

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

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

析構(gòu)函數(shù)

析構(gòu)函數(shù)用來(lái)釋放當(dāng)前對(duì)象使用到的內(nèi)存空間,當(dāng)對(duì)象跳出其作用域范圍后就會(huì)執(zhí)行析構(gòu)函數(shù)( 除非是有智能指針出現(xiàn)循環(huán)引用的情況,無(wú)法釋放,導(dǎo)致泄露 )。 C++中析構(gòu)函數(shù)和構(gòu)造函數(shù)相反,會(huì) 優(yōu)先調(diào)用子類的析構(gòu)函數(shù)再調(diào)用父類的析構(gòu)函數(shù) 。 如下代碼:

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;
};
運(yùn)行結(jié)果:
~Son
~Father

拷貝構(gòu)造

C++中拷貝構(gòu)造函數(shù)格式:

  • 格式1 :帶const參數(shù) Complex(const Complex& c) { … } 表示以常量對(duì)象作為參數(shù)
  • 格式2 :不帶const參數(shù) Complex(Complex& c) { … } 表示以非常量作為參數(shù)進(jìn)行拷貝 如下代碼:
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();
};
打印結(jié)果:
real:1 imag:2
real:2 imag:3

拷貝構(gòu)造函數(shù)和構(gòu)造方法類似, C++編譯器會(huì)給我們提供默認(rèn)的拷貝構(gòu)造函數(shù) 。 將上面代碼的拷貝構(gòu)造函數(shù)刪除后:

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();
};

依然可以執(zhí)行拷貝構(gòu)造,此時(shí)c2使用了默認(rèn)拷貝構(gòu)造函數(shù)進(jìn)行賦值。

拷貝構(gòu)造的幾種調(diào)用形式:

  • 1.當(dāng)用一個(gè)對(duì)象去初始化同類的另一個(gè)對(duì)象時(shí)

    Complex c2(c1);
    Complex c2 = c1;
    

    這兩天語(yǔ)句是等價(jià)的。但是要 注意此時(shí)Complex c2 = c1是一個(gè)初始化語(yǔ)句,并非一個(gè)賦值語(yǔ)句。賦值語(yǔ)句是一個(gè)已經(jīng)初始化后的變量 。 如下:

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

    賦值語(yǔ)句不會(huì)觸發(fā)拷貝構(gòu)造 。

  • 2.當(dāng)對(duì)象作為一個(gè)函數(shù)形參時(shí),此時(shí)也會(huì)觸發(fā)對(duì)象的拷貝構(gòu)造

    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);
    };
    
    運(yùn)行結(jié)果:
    real:1 imag:2
    complex copy
    real:2 imag:3
    

    可以看到運(yùn)行結(jié)果觸發(fā)了Complex的拷貝構(gòu)造 以對(duì)象作為函數(shù)的形參,在函數(shù)被調(diào)用時(shí),生成的形參要用復(fù)制構(gòu)造函數(shù)初始化,這會(huì)帶來(lái)時(shí)間上的開(kāi)銷。 如果用對(duì)象的引用而不是對(duì)象作為形參,就沒(méi)有這個(gè)問(wèn)題了 。

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

    但是以引用作為形參有一定的風(fēng)險(xiǎn),因?yàn)檫@種情況下如果形參的值發(fā)生改變,實(shí)參的值也會(huì)跟著改變。 最好的方法就是將函數(shù)形參聲明為const類型的引用 。

    void func(const Complex& c) {
        cout << "real:" << c.real << " imag:" << c.imag << endl;
    }
    
  • 3.對(duì)象作為函數(shù)返回值返回時(shí),也會(huì)觸發(fā)拷貝構(gòu)造。

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

    可以看到此時(shí)func函數(shù)中的return c處會(huì)觸發(fā)一次拷貝構(gòu)造,并將拷貝后的對(duì)象返回。 這點(diǎn)通過(guò)函數(shù)hack過(guò)程也可以看出來(lái):此處call方法執(zhí)行的是拷貝構(gòu)造方法

    圖片

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    Labview 之面向對(duì)象編程。 里面有個(gè)例子 和視頻教程地址

    Labview 之面向對(duì)象編程。 里面有個(gè)例子 和視頻教程地址Labview 之面向對(duì)象編程。
    發(fā)表于 12-29 10:16

    C++ 面向對(duì)象多線程編程下載

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

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

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

    C++課件

     C++面向對(duì)象程序設(shè)計(jì) 面向對(duì)象思想的由來(lái)面向
    發(fā)表于 04-10 13:41 ?0次下載

    Visual C++面向對(duì)象與可視化程序設(shè)計(jì)習(xí)題解析與編程實(shí)

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

    C++編程思想

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

    面向對(duì)象的程序設(shè)計(jì)(C++

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

    C#入門教程之面向對(duì)象編程簡(jiǎn)介的詳細(xì)資料概述

    本文檔的主要內(nèi)容詳細(xì)介紹的是C#入門教程之面向對(duì)象編程簡(jiǎn)介的詳細(xì)資料概述主要學(xué)習(xí)的目標(biāo)是1.面向對(duì)象
    發(fā)表于 12-05 11:54 ?35次下載
    <b class='flag-5'>C</b>#入門教程<b class='flag-5'>之面向</b><b class='flag-5'>對(duì)象</b><b class='flag-5'>編程</b>簡(jiǎn)介的詳細(xì)資料概述

    C++語(yǔ)言和面向對(duì)象程序設(shè)計(jì)教程

    章至第11章介紹符合C++國(guó)際標(biāo)準(zhǔn)的C++面向對(duì)象程序設(shè)計(jì)思想和方法;第12章和第13章分別介紹面向
    發(fā)表于 03-02 08:00 ?6次下載

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

    一、STM32與面向對(duì)象編程上一章中提到了,C++的核心之一就在于面向對(duì)象
    發(fā)表于 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語(yǔ)言面向對(duì)象編程應(yīng)用及優(yōu)勢(shì)

    既然面向對(duì)象是一種編程思想,而編程語(yǔ)言只是一種工具,那么,思想與工具之間就不存在一種強(qiáng)耦合的關(guān)系
    發(fā)表于 11-10 12:00 ?1759次閱讀
    嵌入式<b class='flag-5'>C</b>語(yǔ)言<b class='flag-5'>面向</b><b class='flag-5'>對(duì)象</b><b class='flag-5'>編程</b>應(yīng)用及優(yōu)勢(shì)

    C語(yǔ)言是怎么面向對(duì)象編程

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

    C/C++之面向對(duì)象編程思想1

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

    C/C++之面向對(duì)象編程思想3

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

    淺談C語(yǔ)言面向對(duì)象編程思想

    C語(yǔ)言是一種面向過(guò)程的語(yǔ)言,但是也可以用結(jié)構(gòu)體和函數(shù)指針來(lái)模擬面向對(duì)象的特性,比如封裝、繼承和多態(tài)。
    發(fā)表于 11-02 12:27 ?1096次閱讀
    RM新时代网站-首页