代码之家  ›  专栏  ›  技术社区  ›  SmacL

C++中具有相似签名的成员函数继承问题

  •  1
  • SmacL  · 技术社区  · 16 年前

    我有一个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进行全局定义的转换,并调用基本成员mystrut*myfunc(lpctstr x);注意,如果我删除了virtual void myfunc(mystrut*x);从Class2的定义中,它编译得很好。

    我可能错过了一些很简单的东西,但我不明白为什么这不起作用。任何想法都非常感谢。

    3 回复  |  直到 16 年前
        1
  •  3
  •   James Curran    16 年前

    这是通过设计来处理所谓的“脆弱的基类”问题。

    假设您有这样的类:

    struct A
    {
        void MyFunc(long)  {...}
    }
    
    struct B : A
    {
        void MyFunc(long) { ... }
    }
    ....
    B  b;
    b.MyFunc(5);
    

    这是我们将称为b:myfunc(long)的,因为ints会安静地转换为long。

    但假设有人后来将结构A改为:

    struct A
    {
        void MyFunc(long)  {...}
        void MyFunc(int)   {...}
    }
    

    现在,如果覆盖的工作方式与您假设的相同,则调用 b.MyFunc(5) 将改为调用a::myfunc(int)——即使您的调用代码和结构b(您实际使用的类)都没有改变。这被认为是更糟糕的一点困惑。

        2
  •  4
  •   AProgrammer    16 年前

    添加

    using Class1::MyFunc;
    

    在第二课堂。类是嵌套的作用域,找到匹配项时停止名称查找。对于嵌套的名称空间(使用相同的解决方案),也会出现相同的问题,但在实践中并不常见。

        3
  •  -1
  •   sergiom    16 年前

    你应该增加到2级

    virtual MyStruct *MyFunc(LPCTSTR x)
    {
        return Class1::MyFunc(x);
    }
    

    或者在调用基类方法时显式指定它:

    a.Class1::MyFunc(Str);