【问题标题】:unexpected behavior on casting铸造时的意外行为
【发布时间】:2011-10-31 14:07:24
【问题描述】:

我对 C++ 在必须进行数学运算时如何转换类型表示怀疑。

下面的代码原样(即只转换为 int 而没有转换为 double )可以正常工作和构建。如果我定义ENABLE_DOUBLE_CAST 不会构建并抱怨operator*。你知道为什么吗?

我的疑惑是2:

  1. 为什么没有将运算符强制转换为双精度,而是在双精度之间的乘法中使用整数。是因为隐式转换吗?
  2. 为什么 WITH 强制转换为双重启用(使语法更加清晰)未被考虑?

谢谢

AFG

class CA{
    int _m;
public:
    CA( int a, int b ){
     _m=a*b;
    }
    operator int (){
        std::cout<< "(CA int cast)" ;
        return _m;
    }
#ifdef ENABLE_DOUBLE_CAST
    operator double(){
        std::cout << "(CA double cat)";
        return 2.3 * _m;
    }
#endif
};

int main( int argc, const char** argv){
    CA obj_2( 10,20 );                  

    double total_1 = 100.0 * obj_2;   
    double total_2 = obj_2 * 100.0;
    return 0;
}

【问题讨论】:

  • 您听说过用户定义的转换,但不是用户定义的operator*?您需要定义后者。实际上,您必须定义两个版本的operator*

标签: c++ casting operators operator-overloading


【解决方案1】:

为什么没有将运算符强制转换为双精度,而是在双精度之间的乘法中使用整数。是因为隐式转换吗?

是的,这是真的。
它使用operator int ()obj_2 转换为int,然后使用内置的operator*(double, int)

为什么没有考虑到启用对double 的强制转换(使语法更加清晰)?

当你为你的类同时提供operator double()operator int () 时,它会产生歧义,是否将obj_2 转换为intdouble,因为它可以使用两个内置的运算符重载,即:

operator*(double, int)
operator*(double, double)

建议:
如果您想避免隐式转换和由此产生的歧义问题,您应该为您的班级重载operator*

operator*(double,CA) and
operator*(CA,int) 

【讨论】:

  • 您好。谢谢你清楚的解释。我一直认为 C++ 内置二元运算符仅限于具有相同类型的参数,因此 operator*(double,double) 或 operator*(int,int)。基本上你是说 C++ 也提供了不同类型的?
  • @Abruzzo Forte e Gentile:是的,所有内置类型的数学运算符都在 C++ 中隐式提供。只有当其中一个操作数是自定义类时,才能重载它们。
【解决方案2】:

原因是两种类型转换的代码不明确,编译器无法决定是使用 int 类型转换还是使用 double 类型类型转换,两者都是合法的。

隐式转换的规则很复杂,我不打算在这里重复它们(实际上需要一页又一页地涵盖所有内容)。但是,如果它普遍认为向您的类添加隐式转换是一个坏主意,因为您已经看到了歧义问题。如果您想将 CA 与 operator* 一起使用,那么最好为您的类定义 operator*。例如

CA operator*(CA x, CA y)
{
  ...
}

CA operator*(CA x, int y)
{
  ...
}

CA operator*(CA x, double y)
{
  ...
}

CA operator*(int x, CA y)
{
  ...
}

CA operator*(double x, CA y)
{
  ...
}

【讨论】:

  • 嗨,约翰。阅读其他帖子,您关于避免它的一般规则很好。如果您不介意,请附带问题!有没有什么情况下这些演员可能会提供一些最低限度的帮助?如果一般来说必须避免它们,为什么它们仍然存在?您有什么用例吗?
  • 我认为最常见的用例是转换为布尔值,假设您想将 CA 类用作布尔值,例如 CA ca = ...; if (ca) ...。如果不引入大量歧义或令人惊讶的转换,这实际上很难做到。不过可以这样做,它被称为 safe bool idiom,这里有一个很好的链接,可以阅读更多内容artima.com/cppsource/safebool.html
  • 谢谢先生!非常感谢!
猜你喜欢
  • 2018-01-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-28
  • 2019-07-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多