我有一个MFC C ++程序,它包含两个类,如下所示;
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);
'
'
}
当我在VS2003代码下编译时,我得到错误C2664:'MyFunc':无法将参数1从'class CString'转换为'struct MyStruct *',而我本来希望编译器选择完成从CString到LPCTSTR的全局定义转换,并调用基本成员MyStruct * MyFunc(LPCTSTR x);注意,如果我删除virtual void MyFunc(MyStruct * x);从Class2的定义来看,编译得很好。
我可能在这里遗漏了一些非常简单的东西,但我无法弄清楚为什么这不起作用。任何想法都非常感激。
答案 0 :(得分:4)
添加
using Class1::MyFunc;
在Class2中。类是嵌套作用域,名称查找在找到匹配时停止。嵌套命名空间(使用相同的解决方案)可能会出现同样的问题,但在实践中不太常见。
答案 1 :(得分:3)
这是设计用于处理所谓的“脆弱基类”问题。
我们假设你有这样的课程:
struct A
{
void MyFunc(long) {...}
}
struct B : A
{
void MyFunc(long) { ... }
}
....
B b;
b.MyFunc(5);
这里我们会调用B:MyFunc(long),因为它会以静默方式转换为long。
但是后来有人将结构A改为:
struct A
{
void MyFunc(long) {...}
void MyFunc(int) {...}
}
现在,如果覆盖像你想象的那样工作,那么对b.MyFunc(5)
的调用将改为调用A :: MyFunc(int)---即使你的调用代码和结构B都没有,你是这个类实际使用,改变了。这被认为有点混乱。
答案 2 :(得分:-1)
你应该加入Class2
virtual MyStruct *MyFunc(LPCTSTR x)
{
return Class1::MyFunc(x);
}
或在调用时明确指定基类方法:
a.Class1::MyFunc(Str);