簡體   English   中英

C++泛型數組實現

[英]C++ generic array implementation

我最近遇到了一個 C++ 招聘測試。 他們在問以下 4 個問題。

  1. 以下 Array 類的實現中至少有 4 個不同的錯誤。
  2. 為其中至少 2 個提供每個錯誤的測試用例。
  3. 為每個錯誤提出修復方案
  4. 假設我們有一個 Array 類的無錯誤實現,你認為它有任何設計問題嗎?
template <class T> class Array {
private:
    T *m_pData;
    unsigned int m_nSize;

public:

    Array(unsigned int nSize) : m_nSize( nSize)
    { 
        if ( m_nSize > 0)
            m_pData = new ( nothrow) T[ m_nSize];
    } 

    virtual ~Array() 
    { 
        if(m_pData != NULL)
            delete m_pData; 
    } 

    bool Set(unsigned int nPos, const T& Value) 
    {
        if(nPos < m_nSize) {
            m_pData[nPos] = Value;
            return true;
        }
        else 
            return false;
    }

    T Get(unsigned int nPos) {
        if(nPos < m_nSize) {
            return m_pData[nPos];
        }
        else 
            return T();
    }
};

問題是我看不到任何錯誤。 是的,有一些奇怪的代碼,例如:

  • 在調用 delete 之前檢查
  • 出站時在 Get 中返回默認值
  • 使用刪除而不是刪除 []

但這些對我來說都不是問題。

以下是我可以一目了然地發現的五個錯誤:

  1. 創建nSize == 0的實例不會初始化m_pData
  2. 如果分配失敗,則m_nSize設置為錯誤值,后續訪問將失敗。
  3. 缺少復制構造函數。
  4. 缺少賦值運算符。
  5. delete應該是delete[] (是的, NULL檢查是多余的)。

這些都是實際的錯誤,沒有任何爭論。 其他弱點(我可以看到)“僅僅是”嚴重的設計缺陷。

一般的:
1. 最好在每個 if-else 上加上花括號,即使是 1 行代碼。 -(有爭議的)
2. 這個if(m_pData != NULL)是多余的。 C++ 檢查 delete 和 delete[] 中的空指針
3. 你應該選擇nullptr不是NULL
4.Get 可以被聲明為 const。 本身不是錯誤
5.人們還在使用匈牙利符號嗎?

錯誤:
1. delete m_pData; 應該是delete[] m_pData;
根據標准,刪除而不是刪除 [] 任何用 new[] 分配的東西都有未定義的行為。
2. 在構造函數中: new 在內存不足的情況下不會拋出異常,但無論如何將 m_nSize 設置為給定的大小。 這可能會導致未來的錯誤 - 如果您嘗試分配 10000 個對象並且失敗,則 Get 和 Set 仍然會超出*(m_pData + nPos)但此內存地址無效。 它實際上應該是: if( m_pData ) {m_nSize = nSize ;}
3. m_pData[nPos]; 在獲取和設置中:再次 - 構造函數不會拋出異常並且m_pData可能為空。您需要檢查m_pData是否不為空。

擴展答案:
我確實意識到這是一個測試,以檢查人們對內存管理、面向對象和一些模板使用的理解。 然而,最好的答案是“沒有必要重新發明輪子, std::vector從我們可能想到的任何幼稚的實現中都更聰明。” 說這是對上述錯誤的補充,確實提高了您對專業 C++ 開發人員會說的話的答案。

四個錯誤: 1.模板類Array { private: T *m_pData; 無符號整數 m_nSize; 它應該是

template <class T>
class Array 
{
    private: T *m_pData; unsigned int m_nSize;

2.在下面的代碼段

Array(unsigned int nSize) : m_nSize( nSize)
{ 
    if ( m_nSize > 0)
        m_pData = new ( nothrow) T[ m_nSize];
}

如果 m_nSize 小於 0 ,則將 m_pData 賦值為 null;

3.在下面的cpode中:

virtual ~Array() 
{ 
    if(m_pData != NULL)
        delete m_pData; 
} 

而不是 delete ,使用 delete[] m_pData ,作為 m_pDatais 數組。

  1. 在 get 和 set 函數中,在訪問之前檢查 m_pData 是否為 NULL 或不為 null。

暫無
暫無

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

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