2

我最近重构了这样的代码(MyClassto MyClassR)。

#include <iostream>

class SomeMember
{
public:
  double m_value;

  SomeMember() : m_value(0) {}
  SomeMember(int a) : m_value(a) {}
  SomeMember(int a, int b)
  : m_value(static_cast<double>(a) / 3.14159 +
            static_cast<double>(b) / 2.71828)
  {}
};


class MyClass
{
public:
SomeMember m_first, m_second, m_third;

MyClass(const bool isUp, const int x, const int y)
{
  if (isUp)
  {
    m_first = SomeMember(x);
    m_second = SomeMember(y);
    m_third = SomeMember(x, y);
  }
  else
  {
    m_first = SomeMember(y);
    m_second = SomeMember(x);
    m_third = SomeMember(y, x);
  }
}
};


class MyClassR
{
public:
SomeMember m_first, m_second, m_third;

MyClassR(const bool isUp, const int x, const int y)
: m_first(isUp ? x : y)
, m_second(isUp ? y : x)
, m_third(isUp ? x, y : y, x)
{
}
};


int main()
{
    MyClass a(true, 1, 2);
    MyClassR b(true, 1, 2);

    using namespace std;
    cout.precision(10);
    cout
        << "a:" << endl
        << "\tfirst: " << a.m_first.m_value 
        << "\tsecond: " << a.m_second.m_value 
        << "\tthird: " << a.m_third.m_value << endl;

    cout
        << "b:" << endl
        << "\tfirst: " << b.m_first.m_value
        << "\tsecond: " << b.m_second.m_value
        << "\tthird: " << b.m_third.m_value << endl;

    return 0;
}
  • 错误是什么,
  • 为什么它会编译(用 VC6和 VC9 警告级别 4测试:没有投诉)和
  • 正确的做法是什么?

我(假设)我已经有了所有这些答案,但我认为这是一个有趣的问题可以分享。

更新
扩展代码,使其具有“复制、粘贴和执行”功能。VC9 也没有给我任何抱怨,所以VC6 不是这里的问题。
为了完整起见,输出为:

a:
        first: 1        second: 2       third: 1.054069532
b:
        first: 1        second: 2       third: 1.004499999
4

3 回答 3

8

我不确定你到底期待什么,但让我们开始吧……</p>

  • 首先,放弃VC6。严重地。使用它是一个巨大的问题,因为它不符合标准并且排除了很多选择。正确使用它就像玩俄罗斯轮盘赌。

  • 你的构造函数m_third没有做你认为它做的事情。您不能像这样编写条件表达式:“几个参数”在 C++中不是有效的表达式,而条件运算符适用于表达式。

  • 代码可以编译,因为它仍然是正确的,只是没有按照您的意愿执行。它不使用“几个参数”,而是评估,仅采用表达式的最后一个值的序列点运算符 (),因此您的条件实际上等效于:isUp ? y : x

  • 正确的方法是使用两个条件:m_third(isUp ? x : y, isUp ? y : x)

  • 第三个构造函数SomeMember是错误的,值可能会溢出,产生一个负值——我非常怀疑这就是你想要的。

于 2010-03-19T07:45:40.240 回答
2
m_third(isUp ? x, y : y, x)

这看起来是错误的。第一个x是无意义的表达式,因为它没有副作用并且没有使用结果,那么两边的:值和副作用相同,因此?:可以消除,因为前面的表达式?也没有副作用。

m_third(y, x)

但现在它没有做原始代码所做的事情......这是错误吗?

于 2010-03-19T07:46:55.647 回答
0

错误是什么正确的方法是什么?

我猜你的意图是展示逗号运算符与三元 ? 结合的某种天真的用法,也许隐藏了一些聪明和意想不到的运算符优先级陷阱,但我认为代码绝对是人为的。如果这是重点,那么我会说“正确的做法”是不要使用 C++ 或在使用之前先学习它。是的,它有许多看起来像“怪癖”的结构,你可以创建很多看起来很奇怪的代码,编译器可以接受。通过使用 C++,我会说你被假定知道这些工具。

为什么编译

因为它没有错误,而且是正确的 C++ 代码,没有歧义。

于 2010-03-19T08:00:10.813 回答