成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

理解C++之構(gòu)造函數(shù)

開發(fā) 前端
本篇文章我們從幾個問題出發(fā),加深一下對 C++ 中構(gòu)造函數(shù)的了解

相信做過Java、C++或者其他面向?qū)ο笳Z言開發(fā)的朋友們一定對構(gòu)造函數(shù)這個概念不陌生。以前初學(xué)C++的時候筆者看過幾次《C++ Primer》這本書,但是每次都是走馬觀花式的快速閱讀, 每次瀏覽完之后內(nèi)心就會冒出兩個字:就這?現(xiàn)如今回想起來真是圖樣圖森破 。

學(xué)習(xí)最忌諱的就是心急如焚,砍柴不磨刀,所謂欲速則不達,一步一個腳印才能走得更穩(wěn)。

由問題開始

下面我們就從幾個問題出發(fā),加深一下對C++中構(gòu)造函數(shù)的了解:

1、構(gòu)造函數(shù)初始化與賦值的問題

以下的這兩個寫法有什么區(qū)別?

class Person {
public:
    Person(const string name, int age);

private:
    string name;
    int age;
};

// 第一種寫法
Person::Person(const string name, int age) {
    this->name = name;
    this->age = age;
}

// 第二種寫法
Person::Person(const string name, int age):name(name),age(age) {
    
}

在這個例子中第二種寫法是使用構(gòu)造函數(shù)初始值的寫法,第一種寫法雖然合法,也沒有錯誤,但是并不是合理的寫法,并不推薦。

那么這兩種寫法有什么區(qū)別呢? 第一種寫法會經(jīng)歷先初始化,再賦值這么兩個過程;而第二種寫法則是直接初始化數(shù)據(jù)成員一步到位。所以這里面會存在一個效率的問題,第二種寫法的效率更高。

我們再看一個例子,如果我們把類的成員使用const修飾呢,結(jié)果會怎樣?

class Person {
public:
    Person(const string name, int age);

private:
    string name;
    const int age;
};

// 第一種寫法,編譯報錯
Person::Person(const string name, int age) {
    this->name = name;
    this->age = age;
}

// 第二種寫法
Person::Person(const string name, int age):name(name),age(age) {

}

我們發(fā)現(xiàn)第一種寫法行不通了,不能編譯通過了,這是因為age被const修飾了,必須在初始化時賦值,所以第一種寫法就不行了,由此看出使用構(gòu)造函數(shù)初始值的寫法更加規(guī)范,更加安全。

建議:在《Effective C++》一書中的第4條"確定對象被使用前已先被初始化"中也強調(diào)了絕對必要使用構(gòu)造函數(shù)初始值

2、成員變量的初始化順序

如下例子,如果外部調(diào)用Point對象的getX方法,能拿到正確的值嗎?答案是不能的,因為成員x比成員y先初始化。

class Point {

public:
    Point(int x, int y);

    int getX() const{
        return x;
    }

    int getY() const{
        return y;
    }

private:
    int x;
    int y;
};

// 本意是把 yVal的值賦值給成員變量y,然后把成員變量y的值賦值給成員變量x
Point::Point(int xVal, int yVal):y(yVal),x(y) {

}

一般按照我們常規(guī)的思維,我們在構(gòu)造函數(shù)中先寫了y,再x,那應(yīng)該是寫初始化y,再初始化x吧?然而事實并不是這樣子的。

起始構(gòu)造函數(shù)初始值是有一定的規(guī)則的:

構(gòu)造函數(shù)初始值列表只說明用于初始化成員的值,而不限定初始化的具體執(zhí)行順序。成員的初始化順序與它們在類定義中的出現(xiàn)順序一致:第一個成員先被初始化, 然后第二個,以此類推。構(gòu)造函數(shù)初始值列表中初始值的前后位置關(guān)系不會影響實際的初始化順序。

所以上面構(gòu)造函數(shù)的寫法中雖然y出現(xiàn)在了x的前面,但是在成員變量聲明的時候是先聲明了x的,所以初始化的時候是先初始化了x,但是把一個未經(jīng)初始化的y賦值給了x,那肯定是不能成功賦值的, 所以通過getX方法獲取到的值也就不是你想要的那個值了。

3、對于繼承而來的派生類的成員初始化順序是怎么樣的呢?

盡管在派生類對象中含有從基類繼承而來的成員,但是派生類并不能直接初始化這些成員。和其他創(chuàng)建了基類對象的代碼一樣,派生類也必須使用基類的構(gòu)造函數(shù)來初始化它的基類部分。 首先初始化基類的部分,然后按照聲明的順序依次初始化派生類的成員。

3、委托構(gòu)造函數(shù)的執(zhí)行順序

所謂委托構(gòu)造函數(shù)就是構(gòu)造函數(shù)相互調(diào)用。

當(dāng)一個構(gòu)造函數(shù)委托給另一個構(gòu)造函數(shù)時,受委托的構(gòu)造函數(shù)的初始值列表和函數(shù)體被依次執(zhí)行。 如果受委托的構(gòu)造函數(shù)體恰好是空的。假如函數(shù)體包含有代碼的話,將先執(zhí)行這些代碼,然后控制權(quán)才會交還給委托者的函數(shù)體。

4、構(gòu)造函數(shù)異常如何捕獲

處理構(gòu)造函數(shù)初始值異常的唯一方法是將構(gòu)造函數(shù)寫成函數(shù)try語句塊。

5、如何讓類不能在棧內(nèi)構(gòu)造

筆者查了下網(wǎng)上的資料說大概就是說將構(gòu)造方法私有化,并且將拷貝構(gòu)造函數(shù)私有化就能禁止類的對象在棧內(nèi)構(gòu)造了。筆者測試了一下其實這并不嚴謹,這樣的做法只能做到在類的外部禁用了棧內(nèi)初始化, 在類的內(nèi)部依然可以使用棧的方式構(gòu)造對象,比如一下例子:

class Data {
public:
// 在類的內(nèi)部依然可以使用棧的方式構(gòu)造
    Data create() {
        Data data = Data();
    }

private:
    Data();
    Data(const Data &data) {

    }

};

經(jīng)過筆者的測試,私有化構(gòu)造函數(shù),再加上使用delete關(guān)鍵字移除拷貝構(gòu)造函數(shù)即可實現(xiàn)禁用類在棧內(nèi)構(gòu)造的功能:

class Data {
public:
    // 不能在棧內(nèi)構(gòu)造,編譯會報錯
    Data create() {
        return Data();
    }

private:
    Data();
    Data(const Data &data) = delete;
};

但是這種做法實在是太過了,而且筆者筆者才疏學(xué)淺,也不知道這種做法會不會造成什么隱藏的坑,如有高手,請賜教。

《More EffectiveC++》一書中第27條:要求(或禁止)對象產(chǎn)生與heap之中,提到將構(gòu)造函數(shù)和析構(gòu)函數(shù)私有化即可達到禁止對象在棧內(nèi)定義的目的。 但是這個做法太過了,比較好的辦法是讓析構(gòu)函數(shù)r成為 private,而構(gòu)造函數(shù)仍為 public。

6、如何讓類不能在堆內(nèi)構(gòu)造對象

使用new在堆內(nèi)構(gòu)造對象主要會調(diào)用構(gòu)造函數(shù)以及new運算符這兩個步驟,所以我們只要把運算符new移除即可:

class Data {
public:
    Data();
    // 重載new運算符,禁止使用new在堆內(nèi)構(gòu)造對象
    void* operator new (size_t size) = delete;
};

然而筆者發(fā)現(xiàn),雖然這樣能夠禁用new在堆內(nèi)構(gòu)造對象,但是我們知道使用 malloc 也能在堆內(nèi)分配對象,只是使用 malloc 不會調(diào)用類的構(gòu)造函數(shù)而已,所以類內(nèi)的所有成員都需要自己手動初始化, 那么有沒有辦法把malloc也禁用掉呢?筆者并不知曉,懇請高手賜教。。。

在《Effective C++》一書中第06條有提到為駁回編譯器自動(暗自)提供的機能,可將相應(yīng)的成員函數(shù)聲明為private并且不予實現(xiàn)。

所以為了達到某個類只能在堆內(nèi)或者只能在棧內(nèi)構(gòu)造的目的可以參考這一條。

總結(jié)一下

  • 誰先聲明誰先初始化,與構(gòu)造函數(shù)中出現(xiàn)的順序無關(guān);
  • 初始化值中的相關(guān)調(diào)用比構(gòu)造函數(shù)中的函數(shù)體優(yōu)先執(zhí)行;
  • 在派生類中首先初始化基類的部分,然后按照聲明的順序依次初始化派生類的成員。
責(zé)任編輯:趙寧寧 來源: 思想覺悟
相關(guān)推薦

2010-01-27 17:16:52

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

2010-01-28 10:49:22

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

2025-02-06 13:23:09

C++函數(shù)參數(shù)

2010-01-22 11:13:16

C++靜態(tài)

2010-01-25 14:00:27

C++類

2010-01-27 16:10:32

C++靜態(tài)構(gòu)造函數(shù)

2010-01-27 10:13:22

C++類對象

2010-01-25 14:43:00

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

2010-02-01 11:01:30

C++靜態(tài)構(gòu)造函數(shù)

2010-01-25 17:05:37

C++語言

2010-02-02 17:39:31

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

2009-08-13 17:30:30

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

2024-02-23 19:17:12

構(gòu)造函數(shù)C++開發(fā)

2023-12-13 10:51:49

C++函數(shù)模板編程

2010-01-20 18:06:06

C++虛基類

2024-12-31 00:07:12

2024-12-06 12:00:00

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

2010-02-05 17:16:05

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

2011-07-20 13:40:09

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

2022-07-26 00:36:06

C#C++函數(shù)
點贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 久久99视频| 欧产日产国产精品国产 | 仙人掌旅馆在线观看 | 亚洲一区二区在线视频 | 日韩欧美国产精品 | 欧美日韩在线一区二区三区 | 夜夜操天天艹 | 午夜伦理影院 | 精品国产一区二区在线 | 国产亚洲一区二区精品 | 婷婷色婷婷| 麻豆国产一区二区三区四区 | 亚洲国产成人av好男人在线观看 | 日本不卡一区 | 一区二区三区四区不卡 | 在线观看www| 国产99免费视频 | 精品国产一区二区国模嫣然 | 在线视频中文字幕 | 福利视频日韩 | 91视频免费在观看 | 国产精品99久久久久久宅男 | 亚洲综合色视频在线观看 | 激情 亚洲| 亚洲成av人影片在线观看 | 精品一区二区三区在线观看国产 | 国产女人与拘做受免费视频 | 日韩精品一区二区在线 | 国产中文字幕av | www.久久.com | 另类视频在线 | 日韩在线免费视频 | 亚洲巨乳自拍在线视频 | 国产午夜精品一区二区三区 | 天天夜干| 成人精品久久久 | 国产一区二区三区亚洲 | 亚洲高清一区二区三区 | 91久色 | 国产婷婷| 国产成人一区二区三区精 |