2012-03-25 74 views
0

以下代码在XCode中编译,但不在VS2008/VS2010中(错误:用户定义的模糊转换)。如果我使用的是一个函数而不是cast操作符,它会遵守而不会出错。这是一个VS错误?重载的转换运算符继承(Visual C++)

#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

您是否可能在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定义运算符int,它将被编译。

3

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

与你的情况开始:编译器不能真的这样做

(int) c; 

它不知道怎么回事,但它可以投ç到的东西,它知道如何投转换成int,但这留下两种选择:

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

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

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

如果编译器选择了一个办法,你不知道它,并diferent编译器可能选择不同的选项! 那么什么是一些解决方案:

  1. 请从B到A,C一个强制类型B和C的是明确的。然后创建一个 强制转换函数,该函数首先将其转换为您想要的类,然后 将其转换为int。这虽然不适用于你正在使用的视觉工作室 ,所以这不适合你的情况。

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

  3. 在A中定义投射操作,但使其调用虚拟功能,该操作将覆盖B 。那样只有一个演员操作,在A中定义, 没有ambiguos的情况。

我觉得第三个选项是在你的情况是最好的,它会是这个样子:

#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。