2

C++で演算子のオーバーロードを使用して対数クラスを実装する際に問題が発生します。

私の最初の目標は、メソッドをどのように実装するかchangeBaseです。頭を包み込むのに苦労していました。

対数の底を変更する背後にある数学を理解しようとしましたが、理解できませんでした。誰かが私にそれを説明してもらえますか?

double私の2番目の目標は、左のオペランドがaで、右のオペランドが対数オブジェクトである操作を実行できるようにすることです。

これが私のログクラスのスニペットです:

// coefficient: double
// base: unsigned int
// result: double
class _log {

 double coefficient, result;
 unsigned int base;

public:

 _log() {
  base = 10;
  coefficient = 0.0;
  result = 0.0;
 }
 _log operator+ ( const double b ) const;
 _log operator* ( const double b ) const;
 _log operator- ( const double b ) const;
 _log operator/ ( const double b ) const;
 _log operator<< ( const _log &b );

 double getValue() const;

 bool changeBase( unsigned int base );
};

あなたたちは素晴らしいです、あなたの時間をありがとう。

4

3 に答える 3

5

2番目の目標は、左のオペランドがdoubleで、右のオペランドが対数オブジェクトである演算を実行できるようにすることです。

_logこれを行うには、名前空間スコープで(つまり、の定義ではなく)演算子を非メンバー関数として宣言する必要があります。

_log operator+(const double a, const _log& b);

のプライベートメンバーにアクセスする必要がある場合は_log、次の定義内で友達として宣言できます_log

friend _log operator+(const double a, const _log& b);

アンダースコア(たとえば)で始まる_log名前は、グローバル名前空間の実装に予約されていることに注意してください。アンダースコアの後に大文字または別のアンダースコアが続く場合、それはどこでも予約されています。別のクラス名を選択することをお勧めします。

于 2010-05-05T03:07:26.770 に答える
3

いくつかのこと

  1. クラスの前で_を使用することは、非常に悪い考え(tm)です。C ++標準から:

17.4.3.2.1グローバル名[lib.global.names] 名前と関数シグネチャの特定のセットは、常に実装用に予約されています。

  • 二重下線(_ _)を含む、または下線で始まり、その後に大文字(2.11)が続く各名前は、あらゆる用途のために実装用に予約されています。
  • アンダースコアで始まる各名前は、グローバル名前空間で名前として使用するために実装に予約されています。165

165)このような名前は、名前空間:: std(17.4.3.1)でも予約されています。

  1. cmathのlog()との衝突のため、logの代わりに_logを使用したと思います。このため、独自のクラスを標準の名前空間に保持することは非常に悪い考えです。たぶん、標準の次のバージョンは_logまたはLogarithmクラスを提供しますか?独自のクラスをラップnamespace somename {}し、を使用して参照しますsomename::Logarithm()

  2. 他の人がすでに述べたように、あなたはあなたの演算子のオーバーロードを友達として宣言する必要があります。あなたが持っているものの代わりに

    log operator+ ( const double b ) const;

    に変更します

    friend log operator+(const double d, const log& l);
    

    名前空間スコープで関数を定義します。

  3. これが基本式の変更の計算です

    基本式の変更

  4. 数学の係数とは、ログで乗算されている部分を意味します。したがって、A log_b(x)=yの場合

    Aは係数、Bは底辺、Yは結果(または他の名前)です

于 2010-05-05T06:15:37.507 に答える
1

いくつかのアイデア:

  1. 先頭にアンダースコアを付けて名前を付けないでください。このような識別子は、CおよびC++では放射性です。
  2. floatを使用した演算の前に、対数間の演算を定義します。
  3. #2をJamesの提案と組み合わせる:

    friend logarithm operator+( const logarithm &l, const logarithm &r );
    
  4. logarithmfloatからを生成するための変換コンストラクターを定義します。

    logarithm::logarithm( double f );
    

    これで、C++はdoubleをまたlogarithmはのいずれか1.0 + my_logに変換しますmy_log + 1.0

  5. クラスに自然対数を実装します。気にしないでくださいbase
  6. 関数の観点からベース変換を定義します。

    double alternate_base( double base ) const;
    

    基数変換は、単純logarithmに代替基数の自然対数で除算することです。整数部分と小数部分を1つにまとめて返すのがおそらく最も便利doubleです。

于 2010-05-05T05:04:20.057 に答える