我正在为图形开发一个类层次结构,其中有一个名为disjoint_union的方法。因为基类包含需要为所有子类更新的属性(如邻接列表),所以我在这个类中放入了一个带有参数graph的方法,如下所示:
class graph {
public:
// ....
void disjoint_union(const graph& g);
}它的两个子类是ugraph (无向图)和dgraph (有向图)。类dgraph需要更新“内邻接”列表,即图中每个顶点的内邻居的邻接列表。因此,我可以将方法graph::disjoint_union声明为虚拟的,这就是故事的结尾。但我不希望这个类有相同的方法(即具有相同的参数类型),因为它会接受无向图。因此,我的“解决方案”(并不是说它真的是一个问题)是:
class dgraph : public graph {
public:
// ....
void disjoint_union(const dgraph& g);
// ....
private:
using graph::disjoint_union;
}如果我这样做:
dgraph dG;
// initialise dG
ugraph uG;
// initialise uG
dG.disjoint_union(uG);编译器会发出一个错误,因为可以接受类dgraph中的私有的唯一名为disjoint_union的方法被声明为ugraph。需要将方法声明为private只是一种变通方法,因为我可以这样做:
graph* dG = new dgraph(); // I know smart pointers should be chosen over raw pointers
// initialise dG
ugraph uG;
// initialise uG
dG.disjoint_union(uG);一些可以被认为是“坏的”的东西,对于像有根的树这样的子类来说,这甚至会进一步加剧:
class rtree : public dgraph {
public:
// ....
void disjoint_union(const rtree& t);
// ....
private:
using dgraph::disjoint_union;
}它必须在进行这样的操作之后更新它自己的属性。显然,rtree::disjoint_union的一个可能实现是:
void rtree::disjoint_union(const rtree& t) {
dgraph::disjoint_union(t);
// update rtree's attributes
}(在其他类中也是如此)。现在,C++17允许这样做:
class graph {
public:
// ....
virtual void disjoint_union(const graph& g);
}
class dgraph : public graph {
public:
// ....
void disjoint_union(const dgraph& g);
// ....
private:
// this time, graph::disjoint_union is not declared as private
// using graph::disjoint_union;
}但是引发了几个警告,包括
graph.hpp:113: warning: ‘virtual void graph::disjoint_union(const graph&)’ was hidden [-Woverloaded-virtual]
113 | virtual void disjoint_union(const graph& g);
| ^~~~~~~~~~~~~~
dgraph.hpp:145: warning: 'dgraph::disjoint_union' hides overloaded virtual function问:有没有更好的方法来重载disjoint_union方法?(比将方法设为私有好)我担心这些警告告诉我不能保证某些东西,比如不调用适当的方法,或者这种重载方式允许调用父类的disjoint_union方法(这是我不想要的)。任何帮助都将不胜感激。
发布于 2020-05-25 17:37:09
是的,您收到此警告是因为签名disjoint_unions方法因参数类型不同而不同。
解决此警告的最佳方法是在派生类中执行类似操作
void disjoint_union(const graph& g)
{
auto* d = dynamic_cast<dgraph*>(&g); // cast to pointer to avoid exceptions
if (!d) {
graph::disjoint_union(g);
return;
}
// YOUR CODE IS HERE
}https://stackoverflow.com/questions/61999436
复制相似问题