错误:将'const Integer'作为'Integer Integer :: pow(int)'的'this'参数传递,丢弃限定符

时间:2016-10-06 01:14:27

标签: c++

我有class ProductSerializer < ActiveModel::Serializer attributes(*Product.attribute_names.map(&:to_sym)) has_one :raw_material end 类应该模拟整数mod n。因此,它有如下构造函数:

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::inverse()

Integer::pow(int)

我遇到的问题是当我去实施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); } } 时:

Integer::isQuadraticResidue() const

我收到以下错误: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

2 个答案:

答案 0 :(得分:3)

这是const正确性的问题,其中const函数正在尝试调用非const函数。

// ...

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

// ....

在这种情况下,thisInteger*中的pow()const Integer*中是isQuadraticResidue();这意味着pow()可以调用isQuadraticResidue(),因为添加CV限定符是合法的,但不是相反(因为pow()必须接受this }作为不合格的Integer*,失去const限定符。)

这是不允许的,因为允许它会意味着isQuadraticResidue()打破了它无法直接或间接修改实例的保证。虽然它本身并没有改变状态,但它假设pow() 确实改变状态,因为pow()也不是const(因此不承诺不改变国家)。因此,isQuadraticResidue()无法调用pow(),因为这样做可能会违反其保证。

考虑到这一点,这个问题有两种解决方案。

  1. const移除isQuadraticResidue()。这会天真地解决问题,但不建议这样做,因为那样你就无法获得const正确性的好处。
  2. 使所有成员函数也不会修改Integer的逻辑状态const。这将需要更多的努力,但总体上更安全。然后,只要const Integer就可以在Integer上调用它们,那么只要它们不在const,您就可以将它们传递给Integer Integer::inverse() const; Integer Integer::squared() const; Integer Integer::pow() const; 。需要修改,给你更大程度的安全。

    If Err.Description = "The DataTable.ImportSheet operation failed. Invalid file." & vbCrLf & "Line (20): DataTable.ImportSheet Environment(" & STPFilePath & "),Environment(" & TestScriptName & ")," & Action2 & "." Then
    

    这需要在功能中进行更改。原型及其定义。

答案 1 :(得分:0)

问题可能是你将pow声明为非const并尝试从isQuadraticResidue()const调用它,所以在c ++中不允许这样做:

const这只调用成员函数,这是const 你应该制作pow这个常量,因为我想这是个坏主意,因为你可能想要更改其中的一些成员数据。

否则使isQuadraticResidue成为非const

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

现在一切都好。正如你在添加类声明后所看到的那样,我们得到错误!