Reputation: 89
i am currently working on a C++ project where i have an abstract interface that is implemented later on. The interface also has a implemented method which my implementation doesn't override. My problem is that when using my implementation, the compiler(MSVC) doesn't see the interface method. What causes this, and how can i resolve it?
Here comes the code.
#include <string>
#include <vector>
using std::string;
class A
{
public:
string name;
};
class interface
{
public:
virtual int num_foo() = 0;
virtual A* foo(int) = 0;
virtual A* foo(string &name){
for ( int i(0); i < num_foo(); i++)
if ( foo(i)->name == name )
return foo(i);
return 0;
}
};
class implementation : public interface
{
public:
virtual int num_foo() { return m_foos.size(); }
virtual A* foo(int i) {
//check range
return &m_foos[i];
}
std::vector<A> m_foos;
};
int main(...)
{
implementation impl;
// impl is properly initialized here
string name( "bar" );
// here comes my problem, the MSVC compiler doesn't see foo(string &name)
// and gives an error
A *a = impl.foo( name );
}
Upvotes: 1
Views: 200
Reputation: 1466
This is only an issue because you're accessing the implementation
interface, which does have a foo
member, as noted already in the answer by @charles-bailey.
Semantically, what you're trying to call is the interface
method foo, so you probably should actually call that:
int main()
{
implementation impl;
string name( "bar" );
interface& interf = impl;
A *a = interf.foo( name );
A *b = interf.foo( 4 );
}
This would also allow you to implement the Non-Virtual Interface idiom, by making implementation::foo
private. You'd still fail if you try to call impl.foo
directly, but you'd fail for all argument types, with the same error.
(I know this question is old, but NVI is older...)
Upvotes: 0
Reputation: 94635
class implementation : public interface{
public:
using interface::foo;
int num_foo() { return m_foos.size(); }
A& foo(int i)
{ //check range
return m_ones[i];
}
vector<A> m_foos;
vector<A> m_ones;
};
Upvotes: 1
Reputation: 791481
Name resolution happens before overload resolution. In impl.foo( name )
, then compiler looks at the implementation
class and finds only virtual A& foo(int i)
. It does not look at the base class as it has found a function with the right name.
To correct this use can add a using interface::foo
declaration to the derived class to pull all of the base versions of foo
into the derived class for the purposes of overload resolution. Usually, I'd prefer to avoid overloaded functions and I'd probably give the variants of foo
different function names.
(Other errors are that you don't define string
, vector
or m_ones
; you attempt to use ->
instead of .
on a reference and you attempt to return 0 in a function returning a reference to an A
.)
Upvotes: 5
Reputation: 127447
To re-publish base methods (such as foo(string)) in a subclass for overloading, add
using interface::foo;
into class implementation.
Upvotes: 3