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 si开发者_如何学Pythonmple here, but I can't figure out why this doesn't work. Any ideas greatly appreciated.
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.
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.
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);
精彩评论