簡體   English   中英

想知道我是否可以為此使用stl智能指針

[英]wondering if I can use stl smart pointers for this

我目前有一個c ++類,如下所示:

template<class T>
class MyQueue {
   T** m_pBuffer;
   unsigned int m_uSize;
   unsigned int m_uPendingCount;
   unsigned int m_uAvailableIdx;
   unsigned int m_uPendingndex;
public:
    MyQueue(): m_pBuffer(NULL), m_uSize(0), m_uPendingCount(0),   m_uAvailableIdx(0),
            m_uPendingndex(0)
    {
    }

    ~MyQueue()
    {
        delete[] m_pBuffer;
    }

    bool Initialize(T *pItems, unsigned int uSize)
    {
        m_uSize = uSize;
        m_uPendingCount = 0;
        m_uAvailableIdx = 0;
        m_uPendingndex = 0;
        m_pBuffer = new T *[m_uSize];
        for (unsigned int i = 0; i < m_uSize; i++)
        {
            m_pBuffer[i] = &pItems[i];
        }
        return true;
    }
};

所以,我有這個指向數組m_pBuffer對象的指針,我想知道是否有可能用c ++智能指針替換這種處理方式? 我知道我可以做類似的事情:

std::unique_ptr<T> buffer(new T[size]);

使用智能指針矢量是正確的選擇嗎? 這是推薦且安全的嗎?

[編輯]根據答案和評論,我嘗試制作一個線程安全的緩沖區數組。 這里是。 請評論。

#ifndef __BUFFER_ARRAY_H__
#define __BUFFER_ARRAY_H__

#include <memory>
#include <vector>
#include <mutex>
#include <thread>
#include "macros.h"

template<class T>
class BufferArray
{
public:
    class BufferArray()
        :num_pending_items(0), pending_index(0), available_index(0)
    {}

    // This method is not thread-safe. 
    // Add an item to our buffer list
    void add(T * buffer)
    {
        buffer_array.push_back(std::unique_ptr<T>(buffer));
    }

    // Returns a naked pointer to an available buffer. Should not be
    // deleted by the caller. 
    T * get_available()
    {
        std::lock_guard<std::mutex> lock(buffer_array_mutex);
        if (num_pending_items == buffer_array.size()) {
            return NULL;
        }       
        T * buffer = buffer_array[available_index].get();
        // Update the indexes.
        available_index = (available_index + 1) % buffer_array.size();
        num_pending_items += 1;
        return buffer;
    }

    T * get_pending()
    {
        std::lock_guard<std::mutex> lock(buffer_array_mutex);
        if (num_pending_items == 0) {
            return NULL;
        }

        T * buffer = buffer_array[pending_index].get();
        pending_index = (pending_index + 1) % buffer_array.size();
        num_pending_items -= 1;
    }


private:
    std::vector<std::unique_ptr<T> >    buffer_array;
    std::mutex                          buffer_array_mutex;
    unsigned int                        num_pending_items;
    unsigned int                        pending_index;
    unsigned int                        available_index;

    // No copy semantics
    BufferArray(const BufferArray &) = delete;
    void operator=(const BufferArray &) = delete;
};

#endif

智能指針向量是個好主意。 在您的類中足夠安全-提供自動內存重新分配。

但是它不是線程安全的,並且在處理由簡單指針提供給您的外部內存方面也不安全。

請注意,當前的實現不會刪除析構函數中的pItems內存,因此,如果在重構后模仿此類,則不應使用智能指針的向量,因為它們將刪除其指針引用的內存。

另一方面,您不能保證外面沒有人不會為提供給Initialize的pItem分配內存。 如果要使用智能指針矢量,則應為此函數制定契約,以明確聲明您的類聲明了該內存等。然后,您應該對調用類的外部代碼進行重新處理以適應新的契約。 如果您不想更改內存處理方式,那么簡單指針向量是您的最佳選擇。 然而,這段代碼是如此簡單,以至於vector並沒有真正的好處。

請注意,這里的開銷是為每個緩沖區創建智能指針類以及創建矢量類。 向量的重新分配會占用更多內存,並且在沒有您直接控制的情況下會發生。

該代碼有兩個問題:

1)違反零/三/五規則:

要解決此問題,這里不需要智能指針。 要表示大小可變的動態數組,請使用std:vector<T*> 這也允許您刪除m_pBufferm_uSize和析構函數。

2)獲取可能的本地數組元素的地址

Initialize ,獲取作為參數傳遞給函數的pItems數組元素的地址。 因此,隊列不擁有元素的所有權。 隊列似乎是一個實用程序類,它根本不可復制:

template<class T>
class MyQueue 
{
   std::vector<T*> m_buffer;
   unsigned int m_uPendingCount;
   unsigned int m_uAvailableIdx;
   unsigned int m_uPendingndex;

    public:
    MyQueue(T *pItems, unsigned int uSize)
    : m_buffer(uSize, nullptr), m_uPendingCount(0),  m_uAvailableIdx(0), m_uPendingndex(0)
    {
        for (unsigned int i = 0; i < uSize; i++)
        {
            m_buffer[i] = &pItems[i];
        }
    }

    private:
    MyQueue(const MyQueue&); // no copy (C++11 use: = delete)
    MyQueue& operator = (const MyQueue&); // no copy (C++11 use: = delete) 

};

注意:

紅鯡魚是本地陣列。 您可能為此考慮了一個智能指針,但這是另一個問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM