gpt4 book ai didi

c++ - 错误 : passing ‘const Integer’ as ‘this’ argument of ‘Integer Integer::pow(int)’ discards qualifiers

转载 作者:行者123 更新时间:2023-11-28 00:00:00 32 4
gpt4 key购买 nike

我有一个 Integer 类,它应该模拟一个整数 mod n。因此,它具有如下构造函数:

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);
}

我收到以下错误:错误:将“const Integer”作为“Integer Integer::pow(int)”的“this”参数传递会丢弃限定符。我认为它与末尾的 const 有关。做什么?

编辑:类头文件看起来像:

#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

最佳答案

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

// ...

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

// ....

在这种情况下,thispow()中的一个Integer*,一个const Integer*isQuadraticResidue() 中;这意味着 pow() 可以调用 isQuadraticResidue(),因为添加 CV 限定符是合法的,但反之则不行(因为 pow() 将不得不接受 this 作为非限定 Integer*,失去 const 限定符)。

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


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

  1. isQuadraticResidue() 中移除 const。这会天真地解决问题,但不推荐这样做,因为那样您将无法获得 const 正确性的好处。
  2. 将所有不修改Integer 逻辑状态的成员函数也设为const。这将需要更多的努力,但总体上更安全。因为它们可以在 const Integer 上调用,就像在 Integer 上调用一样,所以您可以将实例作为 const< 传递 每当它们不需要修改时,为您提供更大程度的安全性。

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

    这需要在函数的原型(prototype)及其定义中进行更改。

关于c++ - 错误 : passing ‘const Integer’ as ‘this’ argument of ‘Integer Integer::pow(int)’ discards qualifiers,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39886006/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com