1

不要关注实际代码,只需阅读问题即可。我有一个函数,它需要 2 个多项式类型的参数:

FiniteFieldElement(int l, Polynomial p, Polynomial irr)
{
    this->l = l;
    this->p = p;
    this->irr = irr;
}

我的理解是,当传递 p 和 irr 时,将调用多项式的复制构造函数。

复制构造函数工作正常,因为我可以在最后通过断点进行验证。

Polynomial(const Polynomial& p)
{
    degree = p.degree;
    modulo = p.modulo;
    if (polynomial != p.polynomial)
    {
        polynomial = new int[degree + 1];
        for (int i = 0; i <= degree; i++)
        {
            polynomial[i] = p.polynomial[i];
        }
    }
}

但是为什么我的实际参数 p 和 irr 的值是错误的(未初始化的)。复制构造函数的结果和实际参数之间会发生什么?如果我将参数更改为参考参数,它工作正常。(注意:多项式没有析构函数,如果有帮助的话)。

编辑:如果我使用复制构造函数声明多项式Polynomial p1(p2),则 p1 会正确初始化。在 FiniteFieldElement 类中,我得到了错误的多项式参数。我完全被难住了。

4

3 回答 3

3

我的理解是,当传递 p 和 irr 时,将调用多项式的复制构造函数。

这只是部分正确。由于Polinomials是按值传递的,因此可能会进行复制(但复制省略可能意味着根本不进行复制),但是在 , 内部FiniteFieldElement(int l, Polynomial p, Polynomial irr)Polynomial将调用 , 的复制赋值运算符,假设this->pthis->irr的类型为Polynomial。因此,您班级的字段是作业的结果,而不是副本。

所以你应该看看你的复制赋值运算符的实现。

于 2013-05-11T17:10:16.723 回答
1

真的在初始化多项式吗?这样做new int[degree_ + 1];不会构造一个初始化的数组,它的值是垃圾。

编辑:除非有另一个很好的理由需要 a int*,否则最好使用 astd::vector作为多项式系数容器。它将简化对象的构造、销毁和分配。

这很好用(这意味着问题出在您没有向我们展示的代码部分:类定义和赋值运算符)

class Polynomial
{
public:

    Polynomial();
    Polynomial( const Polynomial& p );
    template <int N> Polynomial(int (&Poly)[N] );

    Polynomial& operator=( const Polynomial& Rhs);

    void Print();

    ~Polynomial();
private:
    int* poly_;
    int degree_;
};

class FiniteFieldElement
{
public:
    FiniteFieldElement( Polynomial P );

    void Print();
private:
    Polynomial p_;
};

和实现:

Polynomial::Polynomial()
{
    degree_ = 0;
    poly_ = new int[degree_ + 1];

    poly_[0] = 1;
}

// excessive, you don't really need this
template <int N> Polynomial::Polynomial(int (&Poly)[N] )
{
    degree_ = N - 1;
    poly_ = new int[degree_ + 1];

    for (int i = 0; i <= degree_; i++)
    {
        poly_[i] = Poly[i];
    }
}

Polynomial& Polynomial::operator=( const Polynomial& Rhs)
{        
    if ( this != &Rhs )
    {
        degree_= Rhs.degree_;

        delete[] poly_;

        poly_ = new int[degree_ + 1];

        for (int i = 0; i <= degree_; i++)
        {
            poly_[i] = Rhs.poly_[i];
        }
    }

    return *this;
}


void Polynomial::Print()
{
    std::cout<< "Degree = " << degree_ << "\n Polynomial = ";
    for (int i = 0; i <= degree_; i++)
    {
        std::cout<< poly_[i] << " ";
    }
    std::cout<<"\n";
}

Polynomial::~Polynomial()
{
    delete[] poly_;
}

Polynomial::Polynomial(const Polynomial& p)
{
    degree_ = p.degree_;
    poly_ = new int[degree_ + 1];

    for (int i = 0; i <= degree_; i++)
    {
        poly_[i] = p.poly_[i];
    }
}

FiniteFieldElement::FiniteFieldElement( Polynomial P )
{
    p_ = P;
}

void FiniteFieldElement::Print()
{
    p_.Print();
}

主要只是:

int main(int argc, _TCHAR* argv[])
{
    int myPoly[] = { 1, 2, 3 };

    Polynomial foo(myPoly);

    FiniteFieldElement bar( foo );

    std::cout<< "Foo:\n";
    foo.Print();
    std::cout<< "Bar:\n";
    bar.Print();

    return 0;
}

如果它在您的机器上运行,请查看它在代码和行为方面与您的实现有何不同。

于 2013-05-11T20:58:10.783 回答
0

感谢大家,原来 Eclipse CDT 调试器给了我错误的值。Visual Studio 中的相同断点(或仅打印值 [参见下面的模数])给了我正确的答案。也许我没有正确使用它,但是当您在调试器中输入监视表达式时,您希望获得正确的值。

Eclipse CDT 错误

于 2013-05-17T18:36:02.360 回答