Reputation: 320
So I am getting some weird behavior with some class hierarchy I am trying to make.I am implementing graphs and I am doing it by making a Graph class that is will be implemented by AdjacencyMatrixGraph and AdjacencyListGraph so they could be used as a Graph by anything that wanted to use them.
I have one pure virtual function in Graph that get's overwritten by the function in AdjacencyMatrixGraph, however I have a non virtual function of the same name, but different signature in Graph. I cannot call the non virtual method of the Graph class when accessing an AdjacencyMatrix class, but when I rename the non virtual method it works fine.
Like this:
When the classes look like this
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)
However if I rename the non virtual method like so
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
This makes no sense to me because I thought the compiler sees addVertex(Vertex, bool) and addVertex(unsigned int,unsigned int, double, bool) as two completely different symbols. So one shouldn't be overridden with inheritance, even if it would it shouldn't be possible because the symbols take different arguments.
Upvotes: 1
Views: 134
Reputation: 1719
In this case AdjacencyMatrixGraph
hides Graph::addVertex(unsigned int from, unsigned int to, double weight, bool bidirectional)
. To bring the function into scope use using
declaration as shown below:
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");
}
Upvotes: 1
Reputation: 145239
The definition in a derived class hides the base class overload declarations.
To bring those into the scope of the derived class, use a using
declaration, like
using Graph::addVertex;
in the derived class.
By the way, this is a FAQ. It's often a good idea to check the FAQ before asking. Or even just in general. :-)
Upvotes: 4