这个问题的答案应该是什么?
What should be the answer of this question?
注:这个问题是我朋友问的。这是在面试考试中给他的。我在大学早期就用 C++ 进行过编程。尽管乍一看这个问题看起来很简单,但我找不到很好的答案。这就是我在这里问的原因。
鉴于下面的 C++ 代码,请回答以下 3 个问题:
- class 应该做什么?
- class 的实施存在重大问题。你能说出它的名字吗?
- 你能给出 3 种不同的方法来解决这个问题(取决于那个 class 的要求规范)吗?
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;
};
- 这个class封装了一个包含任何类型值的数组。类似于
RAII
[See Here}
- 没有复制语义。
解决此问题的方法
- 使用
std::vector
- 实施"The rule of three"/"The rule of five"/"The rule of zero"[See Here]
- 允许在构造数组后更改数组的大小。
- 初始化为
nullptr
- 代替整数,使用
std::size
或size_t
- 更改变量名
size
,当使用using namespace std
时可能会与std::size
冲突。
- 当
nullptr
用于初始化值时,将 if(data) delete[] data;
替换为 delete[] data;
。
- 在
getValue
和setValue
中实现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
.
类型
成员函数 setValue
和 getValue
应该抛出异常 std::out_of_range
.
应该为 const
和 non-const
对象重载函数 getValue
,并相应地 return const
或 non-const reference
元素的阵列。
最好声明(也)operator []
。
希望初始化数组
data = new T[size] {};
此外,class 应有一个名为 size()
的成员函数,它 return 是数组中元素的数量。否则 class 的用户将无法正确指定索引。
而且我认为 class 的迭代器也应该被提及。:)否则 class 不是很有用并且不能与标准算法一起使用,例如 std::fill
.:)
注:这个问题是我朋友问的。这是在面试考试中给他的。我在大学早期就用 C++ 进行过编程。尽管乍一看这个问题看起来很简单,但我找不到很好的答案。这就是我在这里问的原因。
鉴于下面的 C++ 代码,请回答以下 3 个问题:
- class 应该做什么?
- class 的实施存在重大问题。你能说出它的名字吗?
- 你能给出 3 种不同的方法来解决这个问题(取决于那个 class 的要求规范)吗?
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;
};
- 这个class封装了一个包含任何类型值的数组。类似于
RAII
[See Here} - 没有复制语义。
解决此问题的方法
- 使用
std::vector
- 实施"The rule of three"/"The rule of five"/"The rule of zero"[See Here]
- 允许在构造数组后更改数组的大小。
- 初始化为
nullptr
- 代替整数,使用
std::size
或size_t
- 更改变量名
size
,当使用using namespace std
时可能会与std::size
冲突。 - 当
nullptr
用于初始化值时,将if(data) delete[] data;
替换为delete[] data;
。 - 在
getValue
和setValue
中实现
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
.
成员函数 setValue
和 getValue
应该抛出异常 std::out_of_range
.
应该为 const
和 non-const
对象重载函数 getValue
,并相应地 return const
或 non-const reference
元素的阵列。
最好声明(也)operator []
。
希望初始化数组
data = new T[size] {};
此外,class 应有一个名为 size()
的成员函数,它 return 是数组中元素的数量。否则 class 的用户将无法正确指定索引。
而且我认为 class 的迭代器也应该被提及。:)否则 class 不是很有用并且不能与标准算法一起使用,例如 std::fill
.:)