C++ 重载基类函数是一种糟糕的做法吗?
假设我有一个基类C++ 重载基类函数是一种糟糕的做法吗?,c++,polymorphism,overloading,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 } }; MySet中的disjoint方法将适用于从MySet派生的每个类,
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
}
};
MySet
中的disjoint
方法将适用于从MySet
派生的每个类,但是当发现两个sortedrange
之间的不相交时,在派生类中重载disjoint
方法是有意义的:
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
}
我读到有充分的理由加入其中,用这种方式颠覆它是不好的做法
有没有更好的方法在不破坏名称隐藏的情况下实现类似的功能?引入名称隐藏的原因是为了处理以下情况:
class Base {
// stuff
};
class Derived : public Base {
// more stuff
public:
static int foo(int);
};
还有一个对派生::foo()
的调用,参数为literal'a'
。然后Base
的开发人员添加了一个新的私有函数Base::foo(char)
。如果不隐藏名称,程序会突然停止编译-对Derived::foo
的调用解析为Base
中的私有成员。名称隐藏可以防止这种情况
在您的示例中,上述内容不是问题(因为使用
意味着您已经知道foo
/不相交
),因此重载基类成员函数本质上并不坏
然而,你的激励示例并不是很激励人-一个
SortedRange
感觉不像是一个MySet
。我怀疑继承是正确的方法。(除非一个SortedRange
应该表示两个极限之间的所有整数,否则不相交的实现是不正确的-它将返回[1,3,5]
,因为它与[2,4,6]
不相交)重写子类中的方法是OO编程的基本思想之一。基类提供了一个默认方法,但如果子类需要以某种方式进行专门化,则可以重写它。更合理的设计是完全避免继承。事实上,我认为你根本不需要上课。只需使用std::set
并将disjoint
转换为一个非成员函数,在迭代器或两个std::set
s上运行(任何适合您的问题的函数)。@Barmar和其他人。他问的是重载问题,而不是覆盖问题。@ChristianHackl这只是一个简单的例子。如果我有更复杂的类,这些标准类在标准库中没有实现。@ Barmar:双调度不受C++的自然支持,但这是当虚拟< /Cult>成员函数具有其自己的基类类型的参数时所需要的。因此,您必须在每个重写函数中使用typeid
/dynamic\u cast
手动检查参数的动态类型,因为ConcreteClassX和ConcreteClassY的每个组合可能需要专门的行为。我不认为这会导致一个真正干净的设计。
class Base {
// stuff
};
class Derived : public Base {
// more stuff
public:
static int foo(int);
};