-1

演算子のオーバーロードを行ったときに、「&」トークンの前にコンストラクタ、デストラクタ、または型変換が必要であるというこのエラーが発生しました。エラーは fixed.cpp の最後の 8 行で発生しました。何を見逃したのかわかりません。どんな助けでも大歓迎です。

これは固定です.hpp

    #ifndef FIXED_HPP_
    #define FIXED_HPP_

    typedef float value_type ;  

    class fixed
    {
     public:
       fixed();
       fixed(value_type integer, value_type fraction); 
       fixed(double val);
       void as_string();
       value_type integer();
       value_type fraction();
       value_type value();
       //~fixed();
       fixed& operator+=(fixed other);

       static const int places=4;   
       static const int places10=10000;  

     private:
       value_type integer_;
       value_type fraction_;   
       value_type value_;
    };

    fixed operator+(fixed a, fixed b);

    #endif

これはfixed.cppです:

    #include "fixed.hpp"

    #include <iostream>
    #include <ostream>
    #include <stdexcept>
    #include <string>
    #include <algorithm>


    using namespace std;

    fixed::fixed():integer_(0), fraction_(0), value_(0){}

    fixed::fixed(value_type integer,  value_type                 fraction):integer_(integer),         fraction_(fraction) 
           {try
       {
        if (fraction_ <0)                          
           throw invalid_argument("Invalid argument. Must be positive.");
       }
            catch (exception& e)
              {
                cout <<"\n"<< e.what() << std::endl;
      }
             while (fraction_>= places10)
                {
                 if(int(fraction_)%10 >=5 && fraction_< (places10*10) )
            fraction_=int(fraction_/10+1);               
         else
            fraction_ =int(fraction_/10);
        }

     value_ = integer_*places10 + fraction_;  
           } 

    fixed::fixed(double val):integer_(int (val)), fraction_( (val- int(val))*places10) 
           { if (val <0)
                {    val = val*(-1);
             if ( int(val*places10*10)%10>=5)
              fraction_ = (fraction_*(-1) +1)*(-1);
        }     
     else
         {
          if (int(val*places10*10)%10>=5)
              fraction_ = fraction_ +1;
         }

     value_ = integer_*places10 + fraction_;  
           }

    void fixed::as_string()
           {    string str;
                string str2;
        while( (int(integer_)/10) >=0 and int(integer_)>0 )
             {
             str.push_back(int(integer_)%10 + 48);
             integer_ = integer_/10;
             //cout<<str<<endl;
             }
        //cout<<"String format: "<<str<<endl;
        reverse(str.begin(), str.end());
        //cout<<"Reversed format: "<<str<<endl;
        str.push_back('.');
        //cout<<"New string: "<<str<<endl;
        while( (int(fraction_)/10 )>=0 and int(fraction_)>0)
             {
             str2.push_back(int(fraction_)%10 + 48);
             fraction_ = fraction_/10;
             //cout<<str<<endl;
             }
        //cout<<"String format: "<<str<<endl;
        reverse(str2.begin(), str2.end());
        str.append(str2);
        cout<<"String representation: "<<str<<endl;
           }   

    value_type fixed::value()
         {
          return   value_;     
         }
    value_type fixed::integer()
         {
          return integer_;
         }
    value_type fixed::fraction()
                {
          return fraction_;
         }
    fixed& fixed::operator+=(fixed other) // error
           { value_ += other.value();
             return *this;     
           }

    fixed operator+(fixed a, fixed b)  //error
          { a+=b;
          return a;}
4

3 に答える 3

4

コードには多くの問題があります。主な問題は以下のとおりです。

fixednamespacestdのメンバーです。あなたは同じ名前を宣言し、あなたのコードclassに悪を持っています。using namespace std;

他のいくつかのポイント:

  1. 常に、グローバルスコープではないことを実践してください。 必要に応じてプレフィックスを付けるか、関数スコープ内に入れusing namespace stdます。std::using
  2. fixed::operator+=(Fixed)、する必要がありfixed::operator+=(const Fixed&)ます; そうしないと、不要なコピーが作成されます。
  3. 上記のコメントはまた真実でoperator+(fixed a, fixed b)あり、さらに、それa += bは間違っています。それは明白a + bに同等でなければなりません
于 2012-06-26T03:17:59.683 に答える
2

Clangは次のエラーを提供します。これにより、何が起こっているのかがより明確になります。

fixed.cpp:90:1: error: reference to 'fixed' is ambiguous
fixed& fixed::operator+=(fixed other) // error
^
./fixed.hpp:6:11: note: candidate found by name lookup is 'fixed'
    class fixed
          ^
/usr/include/c++/4.2.1/bits/ios_base.h:950:3: note: candidate found by name lookup is 'std::fixed'
  fixed(ios_base& __base)
  ^
于 2012-06-26T03:20:02.357 に答える
2

これは、 を使用してはならない理由の古典的な例using namespace std;です。同じ名前空間に同じ識別子を持つことで、名前空間汚染と呼ばれるものを引き起こしています (std からすべてが取り込まれたため)。

まず、std名前空間の一部を、必要な場合にのみ取り込みますusing std::something;。またはさらに良いことに、 の価値を理解することを学びstd::ましょう。標準ライブラリが生きて呼吸する C++ が上達すれば、生活がずっと楽になります。

第二に、悪い習慣は言うまでもなく、スタイルを考慮すると、コードの多くは壊滅的です。あなたは次のようなものを紹介しています:

fixed& operator+=(fixed other);

これには多くの問題がありますが、最も顕著なものは constness の欠如と、実際にクラスのインスタンスを値渡しし、コピー コンストラクターを呼び出して不要な複製を作成しているという事実です。使用する必要がある理由constは、プログラマーの安全性の問題と優れた実践です。おわかりのように、入力値を読み取って、演算子の戻り値である答えを作成するだけで済みます。したがって、不変にすることで、結果を安全に計算して返すことができます。

fixed& operator+=(const fixed& other); // preferably call *other* rhs (righthandside)

クラスの名前を完全に削除using namespace std;または変更すると、最初の問題はなくなります。しかし、演算子のオーバーロードには多くの問題があります。具体的には、どのようにパラメーターを取り込み、どのようにそれらを返すか、そして実際に必要なことだけを行うように状況を管理する (不要なコピーや一時的なものを回避する) ことです。

于 2012-06-26T03:32:33.263 に答える