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

詳解C++中特殊類設(shè)計

 更新時間:2023年07月16日 09:26:23   作者:南猿北者  
這篇文章主要為大家詳細介紹了C++中關(guān)于特殊類設(shè)計的相關(guān)知識,文中的示例代碼講解詳細,對我們學(xué)習(xí)C++有一定的幫助,感興趣的可以了解一下

設(shè)計一個不能拷貝的類

類之間的拷貝主要是通過拷貝構(gòu)造和賦值運算符之間來實現(xiàn)的;

為此,我們只要讓外部用戶無法正常調(diào)用這兩個函數(shù)就行了;

C++98作法

將拷貝構(gòu)造、賦值運算符的聲明進行私有化處理;(不建議設(shè)為protected,不然的話在子類中就能進行拷貝了)

這樣在外部就會因為訪問限定符的限制不能進行拷貝:

class NoCopy
{
public:
    NoCopy(int val=0):_val(val) {}
private:
    NoCopy(const NoCopy&);
    NoCopy& operator=(NoCopy&);
    int _val;
};

C++11作法

C++只用delete關(guān)鍵字可以不讓默認拷貝構(gòu)造和默認賦值運算符重載默認生成,我們只要自己不去手寫拷貝構(gòu)造和賦值運算符重載就可以了:

class NoCopy
{
public:
    NoCopy(const NoCopy&) = delete;
    NoCopy& operator=(NoCopy&) = delete;
    NoCopy(int val=0):_val(val) {}
private:
    int _val;
};

設(shè)計一個類只允許在堆上創(chuàng)建對象

思路1:

1.封構(gòu)造:防止在類外隨意創(chuàng)建對象

2.設(shè)計一個成員函數(shù)接口來創(chuàng)建對象,讓用戶只能通過這個函數(shù)接口來創(chuàng)建對象,并且創(chuàng)建出來的對象一定是堆上的;(該函數(shù)不一定非要是靜態(tài)的,非靜態(tài)的函數(shù)也是可以完成用于創(chuàng)建對象的);

3.封拷貝:防止在在類外利用特定函數(shù)接口創(chuàng)建出來的對象在其它地方利用拷貝構(gòu)造實例化對象;(移動構(gòu)造也可以考慮封一下)

class HeapOnly
{
public:
    //利用靜態(tài)成員函數(shù)來創(chuàng)建對象
    //調(diào)用方法:HeapOnly::GetHeapOnly1();
    static HeapOnly& GetHeapOnly1(int val=0)
    {
        return *(new HeapOnly(val));
    }
    //利用非靜態(tài)成員函數(shù)創(chuàng)建對象
    //調(diào)用方法:
    // HeapOnly*p=nullptrl;
    //p->GetHeapOnly2();
    HeapOnly& GetHeapOnly2(int val=0)
    {
        return *(new HeapOnly(val));
    }
private:
    //封拷貝:放在在類外利用GetHeapOnly()創(chuàng)建出來的對象在其它地方拷貝構(gòu)造
    //移動構(gòu)造也可以考慮封一下
    HeapOnly(HeapOnly&&) = delete;
    HeapOnly(const HeapOnly&) = delete;
    HeapOnly&operator=(const HeapOnly&) = delete;
    //封構(gòu)造:防止在類外隨意創(chuàng)建對象
    HeapOnly(int val = 0) :_val(val) {}
    int _val;
};

思路2:

1.封析構(gòu):那么就無法在靜態(tài)區(qū)、棧區(qū)創(chuàng)建對象,因為這些地方在對象生命周期到了過后編譯器無法在外部調(diào)用析構(gòu),自然的編譯器就不允許在這些地方創(chuàng)建對象;

2.那么自然的我們最后在堆區(qū)上創(chuàng)建的對象也無法使用delete來釋放資源,但是為了避免內(nèi)存泄漏,我們可以在類內(nèi)封裝一個destory函數(shù)來進行手動調(diào)用釋放資源;

class HeapOnly
{
public:
    void destroy()
    {
        delete this;
    }
    HeapOnly(int val = 0) :_val(val) {}
private:
    ~HeapOnly()
    {}
    int _val;
};

設(shè)計一個類只允許在棧上創(chuàng)建對象

思路:

1.封構(gòu)造:防止在類外任意構(gòu)造

2.設(shè)計一個在棧上創(chuàng)建對象的接口,讓用戶只能通過該函數(shù)獲取對象

3.注意不要封拷貝!之所以能夠在棧上創(chuàng)建對象就多虧了拷貝構(gòu)造?。ɡ媒涌讷@取到的對象拷貝構(gòu)造類外棧上的對象)

class StackOnly
{
public:
    static StackOnly GetStackOnly1(int val = 0)
    {
        return StackOnly(val);
    }
     StackOnly GetStackOnly2(int val = 0)
    {
        return StackOnly(val);
    }
private:
    StackOnly(int val=0) :_val(val) {}
    int _val;
};

設(shè)計一個類不能被繼承

思路1:

1、封構(gòu)造:也就是將構(gòu)造私有化,那么子類就無法訪問父類的私有成員,子類在初始化的時候就無法調(diào)用父類的構(gòu)造函數(shù)來初始化,就無法完成對于父類的繼承!

class A
{
private:
    A(int a = 0) :_a(a) {}
        int _a;
};
class B :public A
{
};

思路2:

利用final關(guān)鍵字修飾類,被final關(guān)鍵字修飾的類無法被繼承;

class A final
{
public:
    A(int a = 0) :_a(a) {}
        int _a;
};
class B :public A
{};

設(shè)計一個類只能實例化一次對象(單例模式)

單例模式簡介:一個類只能創(chuàng)建一個對象,即單例模式,該模式可以保證系統(tǒng)中該類只有一個實例,并提供一個訪問它的全局訪問點,該實例被所有程序模塊共享。比如在某個服務(wù)器程序中,該服務(wù)器的配置信息存放在一個文件中,這些配置數(shù)據(jù)由一個單例對象統(tǒng)一讀取,然后服務(wù)進程中的其他對象再通過這個單例對象獲取這些配置信息,這種方式簡化了在復(fù)雜環(huán)境下的配置管理.

單例模式有兩種實現(xiàn)模式

1. 餓漢模式

還沒啟動main函數(shù)之前就已經(jīng)將對象創(chuàng)建好了;

2. 懶漢模式

程序啟動的時候,第一次獲取對象時進行創(chuàng)建;

餓漢模式

思路:

1.封構(gòu)造:避免在類外隨意創(chuàng)建對象;

2.提供一個函數(shù)接口(GetInstance())來獲取這個唯一對象;

3.用一個封裝一個本類的靜態(tài)指針,一開始就初始化這個指針,該指針指向一個堆區(qū)的對象;

class Hungry
{
public:
    static Hungry&GetInstance()
    {
        return *_ptr;
    }
private:
    Hungry(int x=int (),const Date&d=Date()):_x(x),_d(d)
    {}
    int _x;
    Date _d;//自定義類型
    static Hungry* _ptr;
};
Hungry* Hungry::_ptr = new Hungry(1,Date(2023,12,31));

餓漢模式總結(jié):

1.使用餓漢模式會加慢程序響應(yīng)的時間,因為餓漢模式是一上來就創(chuàng)建對象,要是這個對象非常大呢?那么創(chuàng)建起來就比較耗時間,這樣會拖慢main函數(shù)的調(diào)用時機!

2.我們無法保證我們程序一運行起來就會立馬使用餓漢模式創(chuàng)建出來的對象,這就會造成餓漢模式下的對象白白占用著空間,卻無法得到有效利用,這是一種浪費!

3.如果這個單例對象在多線程高并發(fā)環(huán)境下頻繁使用,性能要求較高,那么顯然使用餓漢模式來避免資源競爭,提高響應(yīng)速度更好。

懶漢模式

思路:

1.封構(gòu)造:避免在類外隨意進行實例化對象;

2.提供一個接口(GetInstance())來專門獲取這個單例對象,同時這個函數(shù)接口具有判斷是不是第一次獲取單例對象的能力;

3.封裝一個static本類指針用于指向單例對象(初始化時為nullptr);

以上就是懶漢模式的雛形,可是上面的懶漢模型真的沒有問題嗎?

當然有,在單線程下沒問題,可是在多線程下,要是多個線程第一次并發(fā)訪問GetInstance()呢?

會不會造成多份sluggard對象被開辟呢?但是_ptr只能存一個sluggard對象的地址,也就意味著那么沒有被_ptr記錄下來的多余sluggard對象會造成嚴重的內(nèi)存泄漏問題,為此我們需要給_ptr指針配一把鎖來保護它的線程安全;

以上就是我們的第一個懶漢模型,上面的懶漢模式還有問題嗎?

還有的!就是當我們每一次都用GetInstance()獲取對象的時候都需要申請鎖和釋放鎖,有一點影響效率,實際上這把鎖只需要第一次訪問時使用就夠了,后面的訪問我們就不需要再進行申請鎖、釋放鎖了,為此我們可以按照如下的方式改:

可是上面的懶漢還是有一點小問題,就是new的時候是會失敗的,new失敗是會拋出異常的,此時執(zhí)行流會直接跳到捕獲該異常的地方,這樣就會造成死鎖問題,因為執(zhí)行流在跳之前是已經(jīng)申請了鎖的,然后是以沒解鎖的狀態(tài)走的,這就必然造成了死鎖問題!為此這把鎖我們需要交給具有RAII風(fēng)格的智能鎖來管理:

class sluggard
{
public:
    static sluggard& GetInstance()
    {
        if (!_ptr)
        {
            lock_guard<mutex> lock(_mux);
            if (!_ptr)
                _ptr = new sluggard;
        }
        return *_ptr;
    }
private:
    sluggard(int c = int(), const Date& d=Date()) :_x(c), _d(d) {}
    int _x;
    Date _d;
    static sluggard* _ptr;
    static mutex _mux;
};
 mutex sluggard::_mux;
sluggard* sluggard::_ptr=nullptr;

懶漢模式總結(jié):

1.相比于餓漢模式,懶漢模式不會拖慢程序的啟動速度,同時是只有需要的時候才進行創(chuàng)建,提高了空間資源的利用率;

2.缺點就是設(shè)計比較復(fù)雜!

以上就是詳解C++中特殊類設(shè)計的詳細內(nèi)容,更多關(guān)于C++特殊類的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • C++實現(xiàn)自頂向下的歸并排序算法

    C++實現(xiàn)自頂向下的歸并排序算法

    這篇文章主要介紹了C++實現(xiàn)自頂向下的歸并排序算法,結(jié)合實例詳細分析了自頂向下的歸并排序算法的原理與具體實現(xiàn)步驟,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-12-12
  • C語言與C++中const的用法對比

    C語言與C++中const的用法對比

    C語言中的const與C++有很大的不同,在C語言中用const修飾的變量仍是一個變量,表示這個變量是只讀的,不可顯示地更改,而在C++中用const修飾過后,就變成常量了
    2022-04-04
  • C語言實現(xiàn)折半查找法(二分法)

    C語言實現(xiàn)折半查找法(二分法)

    這篇文章主要為大家詳細介紹了C語言實現(xiàn)折半查找法,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-11-11
  • C++中抽象類和接口的區(qū)別介紹

    C++中抽象類和接口的區(qū)別介紹

    抽象類(abstract class)和接口(interface)的概念是面向?qū)ο笤O(shè)計中常用的概念, 也是比較容易混淆的概念. 在這里, 我提出一種區(qū)分它們的思路
    2013-04-04
  • C++中模板(Template)詳解及其作用介紹

    C++中模板(Template)詳解及其作用介紹

    這篇文章主要介紹了C++中模板(Template)的詳解及其作用介紹,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-09-09
  • C語言鏈表實現(xiàn)學(xué)生成績管理系統(tǒng)

    C語言鏈表實現(xiàn)學(xué)生成績管理系統(tǒng)

    這篇文章主要為大家詳細介紹了C語言鏈表實現(xiàn)學(xué)生成績管理系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-07-07
  • C++中std::for_each的使用

    C++中std::for_each的使用

    std::for_each是C++標準庫中的一個算法,用于遍歷容器并對每個元素執(zhí)行指定的操作,本文就來介紹一下C++中std::for_each的使用,感興趣的可以了解一下
    2025-04-04
  • c++編程學(xué)習(xí)的技巧總結(jié)

    c++編程學(xué)習(xí)的技巧總結(jié)

    在本篇文章里小編給大家分享了關(guān)于c++編程學(xué)習(xí)的技巧以及知識點總結(jié),需要的朋友們學(xué)習(xí)下。
    2019-03-03
  • OpenCV圖像處理基本操作詳解

    OpenCV圖像處理基本操作詳解

    這篇文章主要為大家詳細介紹了OpenCV圖像處理基本操作,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-03-03
  • C語言多文件編寫詳解

    C語言多文件編寫詳解

    這篇文章主要介紹了C語言多文件編寫,是C語言入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下,希望能夠給你帶來幫助
    2021-09-09

最新評論