简体   繁体   English

C++泛型数组实现

[英]C++ generic array implementation

I came lately across a C++ recruitment test.我最近遇到了一个 C++ 招聘测试。 They are asking the 4 following questions.他们在问以下 4 个问题。

  1. There are at least 4 different bugs in the implementation of the following Array class.以下 Array 类的实现中至少有 4 个不同的错误。
  2. Provide for at least 2 of them a test case for each bug.为其中至少 2 个提供每个错误的测试用例。
  3. Propose a fix for each bug为每个错误提出修复方案
  4. Assuming we have a bug-free implementation of Array class, do you think there are any design problems with it?假设我们有一个 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();
    }
};

The problem is I can see no bug.问题是我看不到任何错误。 Yes, there are some weird code like:是的,有一些奇怪的代码,例如:

  • checking before calling delete在调用 delete 之前检查
  • returning a default value in Get when outofbounds出站时在 Get 中返回默认值
  • using delete instead of delete []使用删除而不是删除 []

But these are no bugs to me.但这些对我来说都不是问题。

Here are the five bugs that I can find at a glance:以下是我可以一目了然地发现的五个错误:

  1. Creating an instance with nSize == 0 will not initialise m_pData .创建nSize == 0的实例不会初始化m_pData
  2. If allocation fails, m_nSize is set to a wrong value, and subsequent access will fail.如果分配失败,则m_nSize设置为错误值,后续访问将失败。
  3. Copy constructor is missing.缺少复制构造函数。
  4. Assignment operator is missing.缺少赋值运算符。
  5. delete should be delete[] (and yes, the NULL check is redundant). delete应该是delete[] (是的, NULL检查是多余的)。

Those are all actual bugs, no argument possible.这些都是实际的错误,没有任何争论。 The other weaknesses (that I can see) are “merely” crippling design flaws.其他弱点(我可以看到)“仅仅是”严重的设计缺陷。

General:一般的:
1. it is the best to put curly braces on each if-else , even for 1 line of code. 1. 最好在每个 if-else 上加上花括号,即使是 1 行代码。 - (arguable) -(有争议的)
2. this if(m_pData != NULL) is redundand. 2. 这个if(m_pData != NULL)是多余的。 C++ checks for null pointers in delete and delete[] C++ 检查 delete 和 delete[] 中的空指针
3. you should opt nullptr isntead of NULL . 3. 你应该选择nullptr不是NULL
4.Get could have been declared as const. 4.Get 可以被声明为 const。 not a bug per-se本身不是错误
5.does people still use the hungarian notation? 5.人们还在使用匈牙利符号吗?

Bugs:错误:
1. delete m_pData; 1. delete m_pData; should be delete[] m_pData;应该是delete[] m_pData;
according to the standard, deleting instead of deleting[] anything that was allocated with new[] has undefined behaviour.根据标准,删除而不是删除 [] 任何用 new[] 分配的东西都有未定义的行为。
2. in the Constructor : new doesn't throw exception in case of insufficiant memory, yet m_nSize is set to the given size anyway. 2. 在构造函数中: new 在内存不足的情况下不会抛出异常,但无论如何将 m_nSize 设置为给定的大小。 that may lead to future bugs - if you try to allocate 10000 objects and you fails, Get and Set still going to excess *(m_pData + nPos) but this memory address is invalid.这可能会导致未来的错误 - 如果您尝试分配 10000 个对象并且失败,则 Get 和 Set 仍然会超出*(m_pData + nPos)但此内存地址无效。 it should be actually : if( m_pData ) {m_nSize = nSize ;}它实际上应该是: if( m_pData ) {m_nSize = nSize ;}
3. m_pData[nPos]; 3. m_pData[nPos]; in Get and Set: again - the constructor doesn't throw an exception and m_pData may be null .you need to check if m_pData is not null.在获取和设置中:再次 - 构造函数不会抛出异常并且m_pData可能为空。您需要检查m_pData是否不为空。

Extended answer:扩展答案:
I do realize this is a test to check the person's understanding in memory management , obejct oriented and some template use.我确实意识到这是一个测试,以检查人们对内存管理、面向对象和一些模板使用的理解。 yet, the best answer will be "there is no need to reinvent the wheel, std::vector is smarter from any naive implementation we might think of."然而,最好的答案是“没有必要重新发明轮子, std::vector从我们可能想到的任何幼稚的实现中都更聪明。” saying this as addition for the bugs above really raise your answer to a something that a professional C++ developer would say.说这是对上述错误的补充,确实提高了您对专业 C++ 开发人员会说的话的答案。

Four Errors : 1. template class Array { private: T *m_pData;四个错误: 1.模板类Array { private: T *m_pData; unsigned int m_nSize;无符号整数 m_nSize; It should be它应该是

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

2.In below code segment 2.在下面的代码段

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

if m_nSize is less then 0 , assigne m_pData to null;如果 m_nSize 小于 0 ,则将 m_pData 赋值为 null;

3.In below cpode : 3.在下面的cpode中:

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

Instead of delete , use delete[] m_pData , as m_pDatais array.而不是 delete ,使用 delete[] m_pData ,作为 m_pDatais 数组。

  1. in both get and set functions check whether m_pData is NULL or not null before accessing.在 get 和 set 函数中,在访问之前检查 m_pData 是否为 NULL 或不为 null。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM