亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

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

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

文章轉自微信 公眾號: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文件當中,我們定義了一個StringBad類,這是C++ Primer當中的一個例子。為什么叫StringBad呢,主要是為了提示,表示這是一個沒有完全開發(fā)好的demo。

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

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

接下來我們來看一下它的實現(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)成員變量。因為聲明只是描述了如何分配內存,但并不真的分配內存。

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

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

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

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

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

然后我們這么使用:

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

會得到一個奇怪的結果:

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

答案是執(zhí)行callme函數(shù)的時候執(zhí)行的,因為callme函數(shù)使用了值傳遞。當callme函數(shù)執(zhí)行結束時,也會調用參數(shù)sb的析構函數(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)又有負數(shù)出現(xiàn)了,這是為什么呢?

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

它等價于:

StringBad st = StringBad(sb);

對應的構造函數(shù)原型是:

StringBad(const StringBad&);

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

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

相關文章

  • 簡單談談C++ 中指針與引用

    簡單談談C++ 中指針與引用

    下面用通俗易懂的話來概述一下,指針-對于一個類型T,T*就是指向T的指針類型,也即一個T*類型的變量能夠保存一個T對象的地址,而類型T是可以加一些限定詞的,引用-引用是一個對象的別名,主要用于函數(shù)參數(shù)和返回值類型,符號X&表示X類型的引用。
    2015-09-09
  • wince禁止程序標題欄上的退出按鈕示例

    wince禁止程序標題欄上的退出按鈕示例

    這篇文章主要介紹了wince禁止程序標題欄上的退出按鈕示例,需要的朋友可以參考下
    2014-02-02
  • 共用體的定義與應用詳細解析

    共用體的定義與應用詳細解析

    共同體的定義類似結構體,不過共同體的所有成員都在同一段內存中存放,起始地址一樣,并且同一時刻只能使用其中的一個成員變量
    2013-08-08
  • C語言創(chuàng)建動態(tài)dll和調用dll(visual studio 2013環(huán)境下)

    C語言創(chuàng)建動態(tài)dll和調用dll(visual studio 2013環(huán)境下)

    本篇文章主要介紹了C語言創(chuàng)建動態(tài)dll和調用dll(visual studio 2013環(huán)境下),非常具有實用價值,需要的朋友可以參考下
    2017-11-11
  • C語言編程之掃雷小游戲空白展開算法優(yōu)化

    C語言編程之掃雷小游戲空白展開算法優(yōu)化

    掃雷是電腦上很經(jīng)典的游戲,特意去網(wǎng)上玩了一會,幾次調試之后,發(fā)現(xiàn)這個比三子棋要復雜一些,尤其是空白展開算法上和堵截玩家有的一拼,與實際游戲差別較大,不能使用光標,下面來詳解每一步分析
    2021-09-09
  • C++二分查找算法實例

    C++二分查找算法實例

    這篇文章主要為大家詳細介紹了C++二分查找算法的實例,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-08-08
  • 純C語言:遞歸二進制轉十進制源碼分享

    純C語言:遞歸二進制轉十進制源碼分享

    這篇文章主要介紹了純C語言:遞歸二進制轉十進制源碼,有需要的朋友可以參考一下
    2014-01-01
  • C++常對象精講_const關鍵字的用法

    C++常對象精講_const關鍵字的用法

    用const修飾的聲明數(shù)據(jù)成員稱為常數(shù)據(jù)成員。變量或對象被 const修飾后其值不能被更新。因此被const修飾的變量或對象必須要進行初始化
    2013-10-10
  • C++實現(xiàn)關機功能詳細代碼

    C++實現(xiàn)關機功能詳細代碼

    大家好,本篇文章主要講的是C++實現(xiàn)關機功能詳細代碼,感興趣的同學趕快來看一看吧,對你有幫助的話記得收藏一下
    2022-01-01
  • C++讀取單個字符操作示例詳解

    C++讀取單個字符操作示例詳解

    這篇文章主要為大家介紹了C++讀取單個字符操作示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-09-09

最新評論