Reputation: 22922
I have an MFC C++ program that contains two classes, as follows;
struct MyStruct
{
'
'
};
class Class1
{
public:
virtual MyStruct *MyFunc(LPCTSTR x);
virtual void MyFunc(MyStruct *x);
'
'
};
class Class2 : public Class1
{
public:
virtual void MyFunc(MyStruct *x);
'
'
};
main()
{
'
'
CString Str = _T("WTF");
Class2 a;
a.MyFunc(Str);
'
'
}
When I compile this under VS2003 code I get error C2664: 'MyFunc' : cannot convert parameter 1 from 'class CString' to 'struct MyStruct *' whereas I would have expected the compiler to pick up the globally defined conversion from CString to LPCTSTR and call the base member MyStruct *MyFunc(LPCTSTR x); Note that if I remove virtual void MyFunc(MyStruct *x); from the definition of Class2 it compiles just fine.
I'm probably missing something pretty simple here, but I can't figure out why this doesn't work. Any ideas greatly appreciated.
Upvotes: 1
Views: 102
Reputation: 4877
you should add to Class2
virtual MyStruct *MyFunc(LPCTSTR x)
{
return Class1::MyFunc(x);
}
or specify explicitly the base class method when you call it:
a.Class1::MyFunc(Str);
Upvotes: -1
Reputation: 103505
This is by design to handle what is called the "fragile base class" problem.
Let's assume you have classes like this:
struct A
{
void MyFunc(long) {...}
}
struct B : A
{
void MyFunc(long) { ... }
}
....
B b;
b.MyFunc(5);
Here's we would call B:MyFunc(long) because ints silently convert to longs.
But say someone later changed struct A to:
struct A
{
void MyFunc(long) {...}
void MyFunc(int) {...}
}
Now, if override worked like you assumed, that the call to b.MyFunc(5)
would change to call to A::MyFunc(int) --- even though neither your calling code nor struct B, the class you are actual using, changed. This was deemed worse a little confusion.
Upvotes: 3
Reputation: 52284
Add
using Class1::MyFunc;
in Class2. Classes are nested scopes and name lookup stop when a match is found. The same problem can occur with nested namespaces (with the same solution), but is less common in practice.
Upvotes: 4