2

私は最近、このようなコードをリファクタリングしました(MyClassMyClassR)。

#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

  • 正しい方法は、2 つの条件を使用することです。m_third(isUp ? x : y, isUp ? y : x)

  • の 3 番目のコンストラクター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

それを行う正しい方法は何ですか?

あなたの意図は、コンマ演算子を 3 進数 ? と組み合わせて使用​​する単純な使用法を示すことだと思います。おそらく、巧妙で予期しない演算子の優先順位の落とし穴が隠されている可能性がありますが、コードは完全に人為的だと思います。これがポイントである場合、「正しい方法」とは、C++を使用しないか、使用する前に最初に学習することです。はい、「癖」のように見える多くの構造があり、コンパイラによって受け入れられる多くの奇妙に見えるコードを作成できます。C++ を使用することで、ツールを知っていると見なされます。

なぜコンパイルするのですか

エラーがなく、あいまいさのない正しい C++ コードであるためです。

于 2010-03-19T08:00:10.813 に答える