C ++通用数组实现

时间:2015-06-29 09:12:48

标签: c++ arrays generics

我最近参加了C ++招聘考试。他们问以下4个问题。

  1. 执行中至少有4个不同的错误 跟随Array类。
  2. 为每个错误提供至少2个测试用例。
  3. 为每个错误提出一个补丁
  4. 假设我们有一个无类别的Array类实现,你认为 它有任何设计问题吗?
  5. 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之前检查
    • 在Outofbounds中获取默认值
    • 使用delete而不是delete []

    但这些对我来说都没有错误。

3 个答案:

答案 0 :(得分:2)

以下是我一眼就能找到的五个错误:

  1. 使用nSize == 0创建实例不会初始化m_pData
  2. 如果分配失败,m_nSize设置为错误值,后续访问将失败。
  3. 缺少复制构造函数。
  4. 缺少作业运算符。
  5. delete应为delete[](是的,NULL检查是多余的。)
  6. 这些都是实际的错误,没有争论可能。其他弱点(我可以看到)“仅仅”削弱了设计缺陷。

答案 1 :(得分:0)

一般:
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可能为null。您需要检查m_pData是否为空。

扩展答案:
我确实认识到这是一个测试,以检查人们对内存管理,面向对象和一些模板使用的理解。然而,最好的答案是&#34;没有必要重新发明轮子,std::vector比我们想象的任何天真的实现更聪明。&#34; 说这是上面的错误的补充真的提高了你对专业C ++开发人员会说的东西的答案。

答案 2 :(得分:0)

四个错误: 1.模板类Array {private:T * m_pData; unsigned int 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 [] m_pData作为m_pDatais数组而不是删除。

    get和set函数中的
  1. 在访问之前检查m_pData是否为NULL。