是否重载基类函数不好的做法?

时间:2018-04-04 19:44:55

标签: c++ polymorphism overloading

假设我有一个基类MySet

class MySet {
    std::vector<int> set;
public:
    bool disjoint(const MySet &other) const {
        // loop over entire set and see if any elements
        //    are in other.set
    }
};

我有一个派生类SortedRange

class SortedRange : public MySet {
    // All integers between two limits
public:
    using MySet::disjoint;
    bool disjoint(const SortedRange &other) const {
         return set.first() > other.set.last()
                 || other.set.first() > set.last();
    }
};

disjoint中的MySet方法适用于从MySet派生的每个类,但是当找到两个SortedRanges之间的不相交时,重载disjoint是有意义的1}}派生类中的方法:

int main() {
    MySet* base = new Set();
    SortedRange* derived = new SortedRange();

    derived->disjoint(*derived); // Can use optimized disjoint function
    derived->disjoint(*base); // Should fall back on base disjoint function
}

我已经读到name hiding是有充分理由加入的,以这种方式颠覆它是不好的做法。

有没有更好的方法来实现这样的事情而不会破坏名称隐藏?

1 个答案:

答案 0 :(得分:1)

引入名称隐藏的原因是为了处理我们的情况:

class Base {
    // stuff
};

class Derived : public Base {
    // more stuff
public:
    static int foo(int);
};

并且调用Derived::foo()并以文字'a'作为参数。然后,Base的开发人员添加了一个新的私有函数Base::foo(char)。没有名称隐藏,程序突然停止编译 - 对Derived::foo的调用解析为Base中的私有成员。名称隐藏阻止了这一点

以上不是您示例中的问题(因为using表示您已经知道foo / disjoint),因此重载基类成员函数本质上并不坏。

然而,你的激励例子不是很激励 - SortedRange感觉不像是MySet。我怀疑继承是正确的方法。 (除非SortedRange应该代表两个限制之间的所有整数,否则disjoint实现不正确 - 它将返回[1, 3, 5],而不是与{[2, 4, 6]不相交1}})