2016-10-06 9 views
0

Integer私は整数mod nをシミュレートするはずです。この質問の完全性のために必要とされるInteger::inverse()Integer::pow(int)は、もありエラー:整数整数:: pow(int)の 'this'引数として 'const Integer'を渡すと修飾子が破棄されます

Integer::Integer(int x) 
    : m(x), n(0) 
{ 

} 

Integer::Integer(int x, int y) 
    : n(y), m(x) 
{ 
    // if this->n greater than 1 
    if (this->n > 1) 
    { 
     // mod this->m by this->n 
     this->m %= this->n; 
     // if this->m is negative 
     if (this->m < 0) 
     { 
      // add this->n to it 
      this->m += this->n; 
     } 
    } 
} 

::私はInteger::isQuadraticResidue() constを実装するために行くときに私がいる

Integer Integer::inverse() 
{ 
    // Extended Euclidean Algorithm 
    int t = 0, 
     r = this->n, 
     newT = 1, 
     newR = this->m;  
    while (newR != 0) 
    { 
     int quotient = r/newR, 
      tCopy = t, 
      rCopy = r, 
      newTCopy = newT, 
      newRCopy = newR; 
     t = newT; 
     newT = tCopy - quotient * newTCopy; 
     r = newR; 
     newR = rCopy - quotient * newRCopy; 
    } 
    if (r > 1) 
    { 
     throw Integer(-1); 
    } 
    if (t < 0) t = t + this->n; 
    return Integer(t, this->n); 
} 

Integer Integer::squared() 
{ 
    return Integer(this->m * this->m, this->n); 
} 

Integer Integer::pow(int x) 
{ 
    // if x less than 0, return this->inverse().pow(-x) 
    if (x < 0) return this->inverse().pow(-x); 
    // if x is 0, return Integer(1) 
    if (x == 0) return Integer(1, this->n); 
    // if x is 1, return *this 
    if (x == 1) return *this; 
    // if x is 2, return this->squared() 
    if (x == 2) return this->squared(); 
    // if x greater than 2 
    if (x > 2) 
    { 
     // if x is even 
     if (x % 2 == 0) 
     { 
      // return this->pow(x/2).squared() 
      return this->pow(x/2).squared(); 
     } 
     // return this->pow(x/2).squared() * (*this) 
     return this->pow(x/2).squared() * (*this); 
    } 
} 

問題は次のようになります。したがって、それはのようなコンストラクタを持っています

bool Integer::isQuadraticResidue() const 
{ 
    // if this->n is zero 
    if (this->n == 0) 
    { 
     // this doesn't belong to Integers mod anything. check for perfect square instead 
     double baseSquareRoot = std::sqrt((double)this->m); 
     return (baseSquareRoot == (double)((int)baseSquareRoot)); 
    } 
    // this is quadratic residue iff this->pow((this->n + 1)/2) == Integer(1, this->n) 
    return (this->pow((n + 1)/2).m == 1); 
} 

エラー:error: passing ‘const Integer’ as ‘this’ argument of ‘Integer Integer::pow(int)’ discards qualifiersが発生します。私は最後にconstと関係があると思う。何ですか?

EDIT:クラスのヘッダファイルは、次のようになります。

#ifndef INTEGER_H 
#define INTEGER_H 

#include <iostream> 

class Integer 
{ 
    public: 
     Integer(int); 
     Integer(int, int); 
     // functions 
     Integer inverse(); 
     Integer squared(); 
     Integer pow(int); 
     bool isQuadraticResidue() const; 
     Integer sqrt(); 
    private: 
     int m, n; 

}; 

#endif 
+0

これを変更する必要はありません。戻り値は 'const_cast 'です。ここでXY問題をやっていますか? –

+0

その質問に答えるには、いいえ。 –

+0

クラスインターフェイスを追加できますか? – Raindrop7

答えて

3

これはconst機能が非const関数を呼び出すしようとしているconst正しさ、の問題です。この状況で

// ... 

bool Integer::isQuadraticResidue() const; 
Integer Integer::pow(int x); 

// .... 

thispow()Integer*あり、isQuadraticResidue()const Integer*pow()は修飾子が失われたInteger*としてthisを受け入れる必要があるので、pow()isQuadraticResidue()を呼び出すことができることを意味します。

許可すると、isQuadraticResidue()は、インスタンスが直接的または間接的に変更されないことを保証しないため、これは許されません。それ自体は状態を変更しませんが、pow()constではないため、状態を変更しないことを約束していないため、pow()に変更されます。このため、isQuadraticResidue()pow()に電話をかけることができません。そのようにすると保証が破綻する危険があるためです。


これを考慮すると、この問題には2つの解決策があります。

  1. isQuadraticResidue()からconstを削除します。これにより、問題は解決されますが、推奨されません。なぜなら、constの恩恵を受けることができないからです。
  2. Integerの論理状態を変更しないすべてのメンバ関数をconstにも作成します。これにはもう少し労力が必要ですが、全体的に安全です。 Integerconst Integerと同様に呼び出すことができますので、変更する必要がない場合はいつでも、constのようにインスタンスを渡すことができ、より安全性が高まります。

    Integer Integer::inverse() const; 
    Integer Integer::squared() const; 
    Integer Integer::pow()  const; 
    

    これは、関数のプロトタイプとその定義の両方で変更する必要があります。

+0

ここに答えがあります。 ^^。よく書かれました。 – adpro

0

問題多分あなたは捕虜のこの非constとしてを宣言し、isQuadraticResidue(からそれを呼び出そうと)constはC++ではそれがそうすることを許可されていないので:

のconstこれが唯一のメンバ関数を呼び出しますこれはconstです あなたはどちらかと言えばpowのこのconstを作るべきですし、おそらくあなたがその中のいくつかのメンバーデータを変更したいと思うので、それは悪い考えです。

そうisQu​​adraticResidueのこの非const

Integer pow(int x);  // this is non const 
bool isQuadraticResidue(); // this is not const 

は、今ではすべてがOKであることを確認してください。あなたがクラス宣言を追加した後で見ることができるように、私たちはエラーをどこで得るか!

関連する問題