【发布时间】:2017-06-01 18:45:16
【问题描述】:
这是一个 100% 的理论问题,可能基于意见。
在一次专业采访中,我得到了一个打印页面,其中包含两个 classes 的大量编写糟糕且格式不正确的代码,以便在语音中逐行分析它们。我们将这些数据结构称为A 和B。没有问题陈述或任何有关预期行为的信息。
但是他们的一个问题真的让我很生气。
在识别出算法的可疑行为以及许多潜在和实际错误之后,他们要求我再识别一个错误。我发现了其他几个明显的问题,但我没有弄清楚他们想从我这里得到什么。好吧,当他们告诉我答案时,我大吃一惊。 A 和 B 的简化版如下(我只留下了他们想法中的方法):
template <typename T>
class A
{
public:
// elements are dynamically allocated on the heap
const T& getValue(unsigned i) const // I'm not even sure it was const
{
// return element at position 'i'
}
virtual void setValue(unsigned i, const T &value)
{
// sets the element at position 'i'
}
};
template <typename T>
class B: public A<T>
{
public:
virtual void setValue(unsigned i, const T &value)
{
// set the element at position 'i' using A<T>::setValue()
// then sort all elements in descending order
}
};
好吧,解决方案不是编译、运行时或逻辑错误。甚至没有这些潜在的风险。 错误如下:由于B::setValue在您放置元素后对数据进行排序,因此您无法测试是否您在给定位置访问的数据与您在该给定位置存储的数据相同。但是使用A 你可以做到这一点。 A 和 B 之间的这种不匹配行为被视为错误(他们补充说这不是错误,但它是错误)。
我认为这完全是一种设计选择(因为B 的全部意义在于维护已排序的数据),我不会说这是一个错误,尤其是没有问题陈述或任何有关预期行为的信息。它甚至不违反多态性的思想或概念。
您会认为这是一个错误吗?
【问题讨论】:
-
在我看来,
setValue的覆盖导致 B 的语义与 A 的语义有很大不同。由于明确指出了B::setValue的预期行为,我想说B从A公开继承可能是一个错误。也许它应该私下继承并实现它自己的getter。 -
可能更适合代码审查?但我有点同意——界面应该对预期的行为是不言自明的。在
setValue内部排序正在推动它... -
我会在“我得到一个打印页面,里面有很多写得很糟糕且格式不正确的代码”这一点退出采访。
-
其实你的面试官想要的答案是首先引起我注意的:如果我有一个容器,我可以在上面调用
setValue(index, value),这是最邪恶的东西之一容器可以避免随后产生getValue(index) == value。这意味着从无序容器继承有序容器的设计决策首先是错误的。这是您应该识别的逻辑错误。与此相比,编译器错误等无关紧要。 -
@plasmacel 完全正确。假设有能力,你的面试官会高度评价这种观察。尽管
B可能与A无关,而不是不存在。
标签: c++ oop polymorphism theory