这个问题的答案应该是什么?

What should be the answer of this question?

注:这个问题是我朋友问的。这是在面试考试中给他的。我在大学早期就用 C++ 进行过编程。尽管乍一看这个问题看起来很简单,但我找不到很好的答案。这就是我在这里问的原因。

鉴于下面的 C++ 代码,请回答以下 3 个问题:

    template<typename T>
    class Array
    {
     public:
        Array(unsigned arraySize):
            data(0), size(arraySize)
        {
            if(size > 0)
                data = new T[size];
        }
        ~Array()
        {
            if(data) delete[] data;
        }

        void setValue(unsigned index, const T& value)
        {
            if(index < size)
                data[index] = value;
        }

        T getValue(unsigned index) const
        {
            if(index < size)
                return data[index];
            else
                return T();
        }

     private:
        T* data;
        unsigned size;
    };
  1. 这个class封装了一个包含任何类型值的数组。类似于 RAII [See Here}
  2. 没有复制语义。
  3. 解决此问题的方法

    • 使用std::vector
    • 实施"The rule of three"/"The rule of five"/"The rule of zero"[See Here]
    • 允许在构造数组后更改数组的大小。
    • 初始化为nullptr
    • 代替整数,使用std::sizesize_t
    • 更改变量名size,当使用using namespace std时可能会与std::size冲突。
    • nullptr 用于初始化值时,将 if(data) delete[] data; 替换为 delete[] data;
    • getValuesetValue
    • 中实现std::out_of_range的抛出

回答者:Bethsheba, Slava, Jesper Juhl来自莫斯科的 Vlad eerorika

What is the class supposed to do?

这是一道看程序无法定论的题。只有作者才能确定他们的意图。没有文档,我们最多只能猜测一下。

我的猜测:这是将动态数组的分配封装在 RAII 容器中的尝试。 std::vector.

的有限和错误版本

There’s a major problem in the implementation of the class. Can you name it?

这里有几个问题;有些比其他的更重要。以下大致按照大问题在前,小问题在后的顺序:

  • class 是可复制和移动的,但复制和移动会导致未定义的行为。
  • 没有简单的方法可以知道 getValue returns 值初始化对象是因为它是索引处的值,还是因为索引超出范围。
  • 无法用于 move-only 个元素。
  • 无法用于 non-default-constructible 个元素。
  • 它不提供迭代器,因此不能与标准算法一起使用。
  • if(data) 在析构函数中是多余的。

Can you give 3 different ways of fixing this problem (Depending on the requirement specifications of that class)?

我假设我提到的第一个问题就是他们所指的问题。

  • 删除copy/moveassignment/constructor。 (不一定是理想的,因为复制和移动可能是有用的操作)。
  • 或者以不会导致未定义行为的方式实施它们。特别是,必须有一个 class-invariant 单个实例具有指向数组的唯一所有权。
  • 或改用std::vector。这也解决了所有小问题。

我想附上 @Arshad 的答案。

对于初学者来说,数组的大小应该是 size_t.

类型

成员函数 setValuegetValue 应该抛出异常 std::out_of_range.

应该为 constnon-const 对象重载函数 getValue,并相应地 return constnon-const reference 元素的阵列。

最好声明(也)operator []

希望初始化数组

data = new T[size] {};

此外,class 应有一个名为 size() 的成员函数,它 return 是数组中元素的数量。否则 class 的用户将无法正确指定索引。

而且我认为 class 的迭代器也应该被提及。:)否则 class 不是很有用并且不能与标准算法一起使用,例如 std::fill .:)