继承和c ++的奇怪行为

时间:2012-11-20 04:14:05

标签: c++ inheritance virtual subclass superclass

所以我得到了一些我试图制作的类层次结构的奇怪行为。我正在实现图形,我正在通过制作一个Graph类来实现它,它将由AdjacencyMatrixGraph和AdjacencyListGraph实现,因此它们可以用作任何想要使用它们的图表。

我在Graph中有一个纯虚函数被AdjacencyMatrixGraph中的函数覆盖,但是我有一个同名的非虚函数,但Graph中的签名不同。在访问AdjacencyMatrix类时,我无法调用Graph类的非虚方法,但是当我重命名非虚方法时,它可以正常工作。

像这样:

当班级看起来像这样

class Graph
{
public:
   virtual void addVertex(Vertex vert, bool bidirectional)=0;
   void addVertex(unsigned int from, unsigned int to, double weight, bool bidirectional)
}

class AdjacencyMatrixGraph : public Graph
{
...
}




AdjacencyMatrixGraph test;
Vertex vert;
test.addVertex(vert,false);   //this statement compiles and works fine
test.addVertex(0,0,10.f,false)  //this statement fails to compile and says cadidates are addVertex(Vertex, bool)

但是,如果我重命名非虚拟方法

class Graph
{
public:
   virtual void addVertex(Vertex vert, bool bidirectional)=0;
   void addVert(unsigned int from, unsigned int to, double weight, bool bidirectional)
}

AdjacencyMatrixGraph test;
Vertex vert;
test.addVertex(vert,false);   //this statement compiles and works fine
test.addVert(0,0,10.f,false)  //this statement compiles and works fine

这对我没有意义,因为我认为编译器将addVertex(Vertex,bool)和addVertex(unsigned int,unsigned int,double,bool)视为两个完全不同的符号。所以不应该用继承覆盖一个,即使它不可能,因为符号采用不同的参数。

2 个答案:

答案 0 :(得分:4)

派生类中的定义隐藏基类重载声明。

要将它们纳入派生类的范围,请使用using声明,例如

using Graph::addVertex;

在派生类中。

顺便说一句,这是一个FAQ。在询问之前检查常见问题解答通常是个好主意。或者甚至只是一般。 : - )

答案 1 :(得分:1)

在这种情况下AdjacencyMatrixGraph隐藏Graph::addVertex(unsigned int from, unsigned int to, double weight, bool bidirectional)。要将函数纳入范围,请使用using声明,如下所示:

class A
{
public:
virtual void foo(int) = 0;
virtual void foo(std::string) { std::cout << "foo(string)" << std::endl; }
};

class B : public A
{
public:
using A::foo; //this unhides A::foo(std::string)
virtual void foo(int) { std::cout << "foo(int)" << std::endl; }
};

int main()
{
B b;
b.foo(1);
b.foo("hello");
}