2017-04-07 11 views
0

私はC++には新しく、Stroustrupの本を読んでいますが、クラスの演算子のオーバーロードに問題があります。分離されたcpp上のC++ ostreamオーバーロード

enter image description here

私はいつものように2つのファイルを持っているし、ヘッダに、私は定義を持っている:

ここ
#ifndef EQUATIONS_H 
#define EQUATIONS_H 

#include<vector> 

namespace equations { 

//solve second degree equation 
class eqSecDeg { 

    private: 
    double a; 
    double b; 
    double c; 
    std::vector<double> solArray; 
    double getDelta(double a, double b, double c); 

    public: 
    eqSecDeg(const double valA, const double valB, const double valC); 
    double getDelta(); 
    std::vector<double> getSolutions(); 

    //thrown with the error 
    class EquationError { 

    private: 
    char* msg; 
    int error_number; 

    public: 
    char* getMsg() { return msg; } 
    EquationError(char* a = "Error.", int err = 0) { 
     msg = a; 
     error_number = err; 
    }; 

    }; 

    //std::ostream& operator << (const std::ostream& x, eqSecDeg& A); 
    //^is commented but it gives the error that it should be declared with only 1 parameter (?)  

}; 

} 

#endif 

あなたがdqsecdegree.cppの実装を見ることができます:

私はこれらの3つのファイルを持っています
#include<math.h> 
#include "dqsecdegree.h" 

namespace equations { 

double eqSecDeg::getDelta(double a, double b, double c) { 
    return (b*b)-(4*a*c); 
} 

double eqSecDeg::getDelta() { 
    return (b*b)-(4*a*c); 
} 

//constructor 
eqSecDeg::eqSecDeg(const double valA, const double valB, const double valC) { 

    if (valA == 0) { 
    throw EquationError("Parameter 'a' cannot be zero.", 1); 
    } 

    a = valA; 
    b = valB; 
    c = valC; 

} 

std::vector<double> eqSecDeg::getSolutions() { 

    double delta = getDelta(a,b,c); 

    if (delta >= 0) { 

    //x1 real and complex 
    solArray.push_back((-b+sqrt(delta))/(2*a)); 
    solArray.push_back(0); 
    //x2 real and complex 
    solArray.push_back((-b-sqrt(delta))/(2*a)); 
    solArray.push_back(0); 

    } else { 

    delta *= -1; 

    //x1 real and complex 
    solArray.push_back(-b/(2*a)); 
    solArray.push_back((sqrt(delta)/(2*a))); 
    //x2 real and complex 
    solArray.push_back(-b/(2*a)); 
    solArray.push_back(-(sqrt(delta)/(2*a))); 

    } 

    return solArray; 

} 

std::ostream& eqSecDeg::operator << (std::ostream& x, eqSecDeg& A) { 
    return x << "something here"; 
} 

} 

SOとgoogleには多くの回答がありますが、正しいものを見つけることができませんでした。私は演算子のオーバーロードをどのように使用しなければならないかを理解しようとしています。 私は、演算子のオーバーロードをヘッダーファイルで宣言し、その実装をcppで正しいと推測します。

  • なぜコンパイラからパラメータが多すぎると伝えられますか?私はそれらの2つ(ostreamとクラス)を必要としていると確信していますか?
  • friendキーワードは、メソッドをクラスの一部にすることなくすべてのメンバーにアクセスできることを知っています。そのキーワードを使用すると、コンパイラはint/double/char/whateverのostream出力の有効な定義がないことを通知します。 オペレータのオーバーロード定義を配置する必要がありますか?

私はどこで(そしてどのように)私はそれを実装する必要があります。なにか提案を?


あまり関連が、メインのこのようなものはない:

//a, b, c taken from the cin istream 
equations::eqSecDeg solver(a,b,c); 
std::vector<double> soluzioni = solver.getSolutions(); 

//here I'd like to call this 
std::cout << solver; 

答えて

1
  1. は.hファイル内の非メンバ関数として関数を宣言。

    std::ostream& eqSecDeg::operator<<(std::ostream& x, eqSecDeg const& A); 
    
  2. あなたが持っているように、.cppファイル内の関数を実装します。非constの代わりにconst&を使用するように更新してください&

  3. 好きな場所で使用できます。

    eqSecDeg A; 
    
    ... 
    
    std::cout << A << std::endl; 
    
+0

私はクラスの内部または外部の.hファイルでそれを宣言する必要がありますか? –

+0

@RaffaeleRossi、クラス外に宣言してください。 –

+0

@RaffaeleRossi、 'operator <<'のために非メンバ関数が使用する方が直感的です。 http://stackoverflow.com/questions/4421706/operator-overloading/34954015#34954015を参照してください。 –

関連する問題