0

試験のための演習のタスクの 1 つに少し問題があります。これはテキストです:

クラス MyFloat にはプライベート変数 float num があります。次のコード行を有効にするメソッドを作成する必要があります。 MyFloat x = 3.5; MyFloat y = x + 3.2 float z = 3.4 + y

そして、私はこのコードを書きます:

#include <iostream>
#include <Windows.h>
using namespace std;

class MyFloat
{
    float num;
public:
    MyFloat(float n)
    {
        num = n;

    }
    MyFloat operator+(MyFloat x)
    {
        float result;
        result = x.num + this->num;
        return result;
    }   
};

int main()
{
    MyFloat x = 3.75;
    MyFloat y = x + 3.2;
    float z = 3.4 + y;
    system("PAUSE");
}

次の行でエラーが発生します。

float z = 3.4 + y;

それは言います:

エラー C2677: バイナリ '+' : 型 'MyFloat' を取るグローバル演算子が見つかりません (または、受け入れ可能な変換がありません)

私は何をすべきか?この問題を解決する方法???

4

4 に答える 4

5

This can be a solution:

class MyFloat
{
    float num;
public:
    MyFloat(float n)
    {
        num = n;
    }

    operator float() const {
        return num;
    }
};

int main()
{
    MyFloat x = 3.75;
    MyFloat y = x + 3.2f;
    float z = 3.4f + y;
}

Initially, I also though about making MyFloat operator+(MyFloat, MyFloat) a non-member friend function but it still doesn't make the line

float z = 3.4 + y;

to compile. The reason is that 3.4 + y will be of type MyFloat and therefore you can't assign it to float z unless you provide a converting operator from MyFloat to float. Buth then, 3.4f + y becomes ambiguous (at least for VS 2010) because it can either call MyFloat operator+(MyFloat, MyFloat) or it can convert y to float and use the built-in operator + for floats.

于 2013-09-05T16:27:21.397 に答える
3

MyFloat + float操作しかなく、 float + MyFloat操作も定義する必要があります。それらは同じではありません。

これをパブリック関数に追加します。

friend float operator+ (const float& lhs, const MyFloat& rhs);

そして、これはクラス外です:

float operator+ (const float& lhs, const MyFloat& rhs) {
    return lhs + rhs.num;
}

注: CassioNeri のコメントに従って編集されました。

于 2013-09-05T16:24:51.797 に答える
0

「キャストからフロート」アプローチを定義する答えに進むことができますが、パブリック API を利用して追加の動作を実装する方が良いと思います。

一般に、単純な「キャスト」ではうまくいきません (たとえば、もしMyFloatだったらどうなりMyMatrixますか?)。

friend以下のアプローチは確かにより冗長ですが、「自分の食べ物を食べる」必要があることを強調しています。つまり、あいまいな暗黙のキャストや関数の束ではなく、独自のパブリック インターフェイスに基づいて追加の動作を実装しようとする必要があります。独自の API を使用する場合: その制限を理解し、変更を加えた場合にメイン クラスの再コンパイルを節約できる可能性があります。

また、クラスへのアクセスをカウントする (または基になる値へのアクセスを制御する) とします。キャスト演算子を使用して、operator float()とのコードを複製する必要がありますfloat value()

というわけで、私のささやかな提案は長くなりますが、私の好みでは、オブジェクト指向の設計原則をよりよく反映しています。

#include<iostream>

class MyFloat {

 public:
  MyFloat(float value):
      m_value(value) { }

  float value() const {
    return m_value;
  }

 private:
  float m_value;

};

// Eat your own food: implement functions using your public interface
// until proven need to do otherwise. This will help you assess the
// usability of your API.
float operator+(const MyFloat& lhs, const MyFloat& rhs) { return lhs.value() + rhs.value(); }
float operator+(const MyFloat& lhs, float rhs) { return lhs.value() + rhs; }
float operator+(float lhs, const MyFloat& rhs) { return lhs + rhs.value(); }

// See, now I can define another operator without need to recompile my
// class (this could have been placed in another file)
std::ostream& operator<<(std::ostream& os, const MyFloat& mf) {
  os<<"MyFloat("<<mf.value()<<")";
  return os;
}

int main() {

  MyFloat x = 3.5;      // would not work if I had declared the constructor as "explicit"
  MyFloat y = x + 3.2;
  MyFloat z = 3.4 + y;

  std::cout<<x<<", "<<y<<", "<<z<<std::endl;
}

出力 (でコンパイルg++ example.cpp -Wall -Wextra):

MyFloat(3.5), MyFloat(6.7), MyFloat(10.1)
于 2013-09-05T19:14:41.227 に答える