65,178
社区成员




#include <iostream>
#include <typeinfo>
using namespace std;
class A {};
class B : public A {};
int main(int argc, char **argv) {
cout << typeid(B::A).name() << endl;
return 0;
}
从上面的代码可以看出,派生类名::基类名 这一写法是没有问题的。
然后,vs05就认为child是从base1::Delegate中那个类继承的。于是你将f2改为f1就正确了。这里很明显违背我们的直觉了。
如果从base2::base2Delegate继承的话,因为base2的基类中没有base2Delegate这个类型,所以编译器必须去base2中查找这一类型。因为typedef在class Delegate之后,所以此时base2中的Delegate覆盖了base2基类名称Delegate,此时编译器认为child是从base2中那个Delegate继承的。f2声明为override也就正常了。
当然,这种违背直觉的绑定是语言和编译器都要尽量避免的。现在的编译器基本都可以正确处理这种情况了。
要在vs05中解决这个问题,我建议你将base1和base2中的Delegate都声明为private,然后分别为他们typedef一个名称。
class base1
{
class Delegate
{
public:
virtual void f1()=0;
protected:
virtual ~Delegate(){}
};
public:
typedef Delegate delegate_type;
base1(){}
virtual ~base1(){}
};
class base2 : public base1::delegate_type
{
class Delegate
{
public:
virtual void f2()=0;
protected:
virtual ~Delegate(){}
};
public:
// 如果没有这个typedef,base2::delegate_type绝对是不存在的
typedef Delegate delegate_type;
base2(){}
virtual ~base2(){}
};
class child:public base2::delegate_type
{
public:
virtual void f2() override;
};
这样子应该不会再发生那种错误了。当然,我手上没有vs05,不能测试,你自己测一下。有结果了顺便告诉我一声~