最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++構(gòu)造函數(shù)一些常見的坑

 更新時間:2022年01月03日 15:31:17   作者:| 梁唐  
這篇文章主要給大家分享的是C++構(gòu)造函數(shù)一些常見的坑,文章圍繞C++構(gòu)造函數(shù)的相關(guān)資料展開關(guān)于C++構(gòu)造函數(shù)坑的內(nèi)容,具有一定的參考價值,需要的小伙伴可以參考一下

文章轉(zhuǎn)自微信 公眾號:Coder梁(ID:Coder_LT)

某一天我們接到了一個需求,需要開發(fā)一個類似于STLstring的類。

我們很快寫好了代碼:

#include <iostream>
#ifndef STRINGBAD_H_
#define STRINGBAD_H_
class StringBad {
? ? private:
? ? ?char *str;
? ? ?int len;
? ? ?static int num_strings;
? ? public:
? ? ?StringBad(const char* s);
? ? ?StringBad();
? ? ?~StringBad();
? ? ?friend std::ostream & operator << (std::ostream &os, const StringBad & st);
};
#endif

在這個.h文件當(dāng)中,我們定義了一個StringBad類,這是C++ Primer當(dāng)中的一個例子。為什么叫StringBad呢,主要是為了提示,表示這是一個沒有完全開發(fā)好的demo。

這里有一個小細(xì)節(jié),我們在類當(dāng)中定義的是一個char *也就是字符型指針,而非字符型數(shù)組。這意味著我們在類聲明當(dāng)中沒有為字符串本身分配空間,而是在構(gòu)造函數(shù)當(dāng)中使用new來完成的,避免了預(yù)先定義字符串的長度。

其次num_strings是一個靜態(tài)成員,也就是說無論創(chuàng)建了多少對象,它都只會保存一份。類的所有成員共享同一個靜態(tài)變量。

接下來我們來看一下它的實(shí)現(xiàn):

#include <cstring>
#include "stringbad.h"

using std::cout;

int StringBad::num_strings = 0;

StringBad::StringBad(const char* s) {
? ? len = std::strlen(s);
? ? str = new char[len+1];
? ? std::strcpy(str, s);
? ? num_strings++;
? ? cout << num_strings << ": \"" << str << "\" object created \n";
}

StringBad::StringBad() {
? ? len = 4;
? ? str = new char[4];
? ? std::strcpy(str, "C++");
? ? num_strings++;
? ? cout << num_strings << ": \"" << str << "\" object created \n";
}

StringBad::~StringBad() {
? ? cout << "\"" << str << "\" object deleted, ";
? ? --num_strings;
? ? cout << num_strings << " left \n";
? ? delete []str;
}

std::ostream & operator<<(std::ostream & os, const StringBad &st) {
? ? os << st.str;
? ? return os;
}

首先,我們可以注意到第一句就是將num_strings初始化成了0,我們不能在類聲明中初始化靜態(tài)成員變量。因為聲明只是描述了如何分配內(nèi)存,但并不真的分配內(nèi)存。

所以對于靜態(tài)類成員,我們可以在類聲明之外使用單獨(dú)的語句進(jìn)行初始化。因為靜態(tài)成員變量是單獨(dú)存儲的,并不是對象的一部分。

初始化要在方法文件也就是cpp文件當(dāng)中,而不是頭文件中。因為頭文件可能會被引入多次,如果在頭文件中初始化將會引起錯誤。當(dāng)然也有一種例外,就是加上了const關(guān)鍵字。

從邏輯上看,我們這樣實(shí)現(xiàn)并沒有任何問題,但是當(dāng)我們執(zhí)行的時候,就會發(fā)現(xiàn)問題很多……

假設(shè)我們現(xiàn)在有一個函數(shù):

void callme(StringBad sb) {
?cout << " ? ?\"" << sb << "\"\n";
}

然后我們這么使用:

int main() {
?StringBad sb("test");
?callme(sb);
?return 0;
}

會得到一個奇怪的結(jié)果:

從屏幕可以看到我們的析構(gòu)函數(shù)執(zhí)行了兩次,一次很好理解應(yīng)該是main函數(shù)退出的時候自動執(zhí)行的,還有一次呢?是什么時候執(zhí)行的?

答案是執(zhí)行callme函數(shù)的時候執(zhí)行的,因為callme函數(shù)使用了值傳遞。當(dāng)callme函數(shù)執(zhí)行結(jié)束時,也會調(diào)用參數(shù)sb的析構(gòu)函數(shù)。

如果我們改成引用傳遞,就一切正常了:

void callme(StringBad &sb) {
?cout << " ? ?\"" << sb << "\"\n";
}

int main() {
?StringBad sb("test");
?callme(sb);
?return 0;
}

這還沒完,我們把代碼再改一下,會發(fā)現(xiàn)還有問題:

int main() {
?StringBad sb("test");
?StringBad sports("Spinach Leaves Bowl for Dollars");
?StringBad sailor = sports;
?StringBad knot;
?StringBad st = sb;
?return 0;
}

執(zhí)行一下,得到:

會發(fā)現(xiàn)又有負(fù)數(shù)出現(xiàn)了,這是為什么呢?

因為我們執(zhí)行了StringBad st = sb這樣的操作,這個操作并不會調(diào)用我們實(shí)現(xiàn)的任何一個構(gòu)造函數(shù)。

它等價于:

StringBad st = StringBad(sb);

對應(yīng)的構(gòu)造函數(shù)原型是:

StringBad(const StringBad&);

當(dāng)我們用一個對象來初始化另外一個對象的時候,編譯器將會自動生成上述的構(gòu)造函數(shù)。這樣的構(gòu)造函數(shù)叫做拷貝構(gòu)造函數(shù),由于我們沒有重載拷貝構(gòu)造函數(shù),因此它不知道要對num_strings變量做處理,也就導(dǎo)致了不一致的發(fā)生。

到此這篇關(guān)于C++構(gòu)造函數(shù)一些常見的坑的文章就介紹到這了,更多相關(guān)C++構(gòu)造函數(shù)的坑內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 簡單分析針對ARM平臺的C語言程序的編譯問題

    簡單分析針對ARM平臺的C語言程序的編譯問題

    這篇文章主要介紹了針對ARM平臺的C語言程序的編譯問題,從優(yōu)化編譯選項的幾個方面進(jìn)行分析,需要的朋友可以參考下
    2015-12-12
  • QT應(yīng)用啟動失敗排查方法小結(jié)

    QT應(yīng)用啟動失敗排查方法小結(jié)

    啟動QT應(yīng)用經(jīng)常會碰到應(yīng)用啟動失敗,qt platform plugin無法啟動,本文就來介紹一下QT應(yīng)用啟動失敗排查方法小結(jié),具有一定的參考價值,感興趣的可以了解以下
    2023-09-09
  • C++11的functional模塊介紹和使用案例

    C++11的functional模塊介紹和使用案例

    functional模塊是C++ 11提供了一組函數(shù)對象和算法,用于增強(qiáng)C++的函數(shù)式編程能力,本文主要介紹了C++11的functional模塊介紹和使用案例,具有一定的參考價值,感興趣的可以了解一下
    2024-02-02
  • C++實(shí)現(xiàn)LeetCode(169.求大多數(shù))

    C++實(shí)現(xiàn)LeetCode(169.求大多數(shù))

    這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(169.求大多數(shù)),本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • C++設(shè)計模式之享元模式(Flyweight)

    C++設(shè)計模式之享元模式(Flyweight)

    這篇文章主要為大家詳細(xì)介紹了C++設(shè)計模式之享元模式Flyweight,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-04-04
  • C++使用boost::lexical_cast進(jìn)行數(shù)值轉(zhuǎn)換

    C++使用boost::lexical_cast進(jìn)行數(shù)值轉(zhuǎn)換

    這篇文章介紹了C++使用boost::lexical_cast進(jìn)行數(shù)值轉(zhuǎn)換的方法,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-06-06
  • C語言讀寫配置文件的方法

    C語言讀寫配置文件的方法

    這篇文章主要介紹了C語言讀寫配置文件的方法,包括C語言讀寫ini配置文件所涉及的文件讀寫技巧,以及完整的源文件及頭文件實(shí)現(xiàn)方法,需要的朋友可以參考下
    2015-07-07
  • 詳解C語言實(shí)現(xiàn)推箱子的基本功能

    詳解C語言實(shí)現(xiàn)推箱子的基本功能

    這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)推箱子的基本功能的方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-02-02
  • C語言銀行儲蓄系統(tǒng)源碼

    C語言銀行儲蓄系統(tǒng)源碼

    這篇文章主要為大家詳細(xì)介紹了C語言銀行儲蓄系統(tǒng)源碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • C語言實(shí)現(xiàn)階乘的示例詳解

    C語言實(shí)現(xiàn)階乘的示例詳解

    在現(xiàn)實(shí)中,我們做數(shù)學(xué)題總會遇到階乘問題,這在計算機(jī)中也不例外。 那我們應(yīng)該怎么實(shí)現(xiàn)呢?下面小編就為大家講解一下C語言中階乘的實(shí)現(xiàn)
    2022-07-07

最新評論

金平| 邹平县| 扶绥县| 菏泽市| 衡东县| 陆丰市| 余江县| 通江县| 庆阳市| 明光市| 名山县| 临夏市| 河北省| 隆化县| 武功县| 湄潭县| 日照市| 夏津县| 镇江市| 乌海市| 合水县| 微山县| 雅江县| 红安县| 南昌县| 新余市| 金乡县| 平乡县| 吉木乃县| 鄱阳县| 古蔺县| 永康市| 博野县| 武乡县| 和平县| 平乐县| 北流市| 芷江| 万州区| 教育| 旬阳县|