重载的转换操作符继承(Visual C ++)

时间:2012-03-25 06:51:17

标签: c++ visual-studio visual-c++

以下代码在XCode中编译,但在VS2008 / VS2010中不编译(错误:用户定义的模糊转换)。如果我使用函数而不是强制转换运算符,则它可以正常运行。这是VS的错误吗?

#include <stdio.h>

class A
{

public:

    virtual operator int() const
    {
        return 1;
    }
};

class B : public virtual A
{

public:

    virtual operator int() const
    {
        return 2;
    }
};

class C : public virtual A, public virtual B
{

public:

};

int main()
{

    C c;

    int i = (int)c;

    printf("%d\n", i);
    return 0;
}

2 个答案:

答案 0 :(得分:3)

发生错误是因为编译器发现它可以用不同的方式执行操作,因为转换是隐式的,编译器必须选择“正确的方法”。

从您的情况开始:编译器无法真正执行类似

的操作
(int) c;

它不知道如何,但是它可以将c转换成它知道如何转换为int的东西,但这留下了两个选项:

(int) A(c);
(int) B(c);

两者同样有效且非常不同!没有办法知道要实施哪个。实际上,如果你有一个B类型的变量b,你甚至可能会发现问题,因为你可以采用两种方式:

(int) b;
(int) A(b);

如果编译器选择了一种方法,你就不知道哪种方式,不同的编译器可以选择不同的选项! 那么有什么解决方案:

  1. 从B到A,C到B和C到A显式转换。然后创建一个 cast函数,首先将其转换为您想要的类,以及 然后将其转换为int。这虽然不适用于视觉 你正在使用的工作室,所以这对你的情况不起作用。

  2. 使B类受到保护,但由于您希望将C转换为B,因此不起作用。 由于将B转换为int的问题,您不能仅仅使A受保护。

  3. 在A中定义强制转换操作,但使其调用虚函数,即B 覆盖。这样,只有一个演员操作,在A中定义, 没有ambiguos案例。

  4. 我认为第三种选择在你的情况下是最好的,它看起来像:

    #include <stdio.h>
    
    class A
    {
    
    protected:
    
        virtual int _int_cast() const
        {
           return 1;
        }
    
    public:
    
        operator int() const
        {
            return this->_int_cast();
        }
    };
    
    class B : public virtual A
    {
    
    protected:
    
        virtual int _int_cast() const
        {
            return 2;
        }
    };
    
    class C : public virtual A, public virtual B
    {
    
    public:
    
    };
    
    int main()
    {
    
        C c;
    
        int i = (int)c;
    
        printf("%d\n", i);
        return 0;
    }
    

    基本上:不要从你继承的类中重新实现重载的强制转换,假设它必须首先转换为基类。还要注意非常类似的重载强制转换,例如,你可以转换为int,然后转换为const int,或者直接转换为const int。

答案 1 :(得分:2)

您是否可能在xcode中收到警告?我无法检查xcode中的代码,但我能够在VS2010中得到一个警告,并且有一个错误。

警告:

main.cpp(30): warning C4250: 'C' : inherits 'B::B::operator int' via dominance main.cpp(19) : see declaration of 'B::operator int'

错误:

main.cpp(37): error C2440: 'type cast' : cannot convert from 'C' to 'int'

警告可能有助于解释您案件中的错误。警告在http://msdn.microsoft.com/en-us/library/6b3sy7ae%28v=vs.80%29.aspx处描述,我建议您仔细阅读。

至于错误,嗯,除了可能导致问题的继承之外,我不能100%确定。如果为c定义operator int,它将编译。