简体   繁体   English

复制构造函数的问题

[英]Problems with copy constructor

Dont pay attention to the actual code, just read the question. 不要注意实际代码,只需阅读问题。 I have a function that takes 2 parameters of type Polynomial: 我有一个函数,它采用类型多项式的2个参数:

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

My understanding is that Polynomial's copy constructor will be called when p and irr are being passed. 我的理解是,当p和irr被传递时,将调用Polynomial的复制构造函数。

The copy constructor is working properly, as I can verify by a breakpoint at the end. 复制构造函数正常工作,因为我可以通过最后的断点进行验证。

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

But why am I getting wrong (uninitialized) values for the actual parameters p and irr. 但为什么我得到实际参数p和irr的错误(未初始化)值。 What could be coming in between the result of the copy constructor and the actual parameters? 复制构造函数的结果和实际参数之间可能会有什么结果? If I change the parameter to a reference parameter, it works fine. 如果我将参数更改为参考参数,它可以正常工作。 (Note: Polynomial has no destructor, if that helps). (注意:多项式没有析构函数,如果有帮助的话)。

EDIT: If I declare a polynomial using the copy constructor Polynomial p1(p2) , p1 gets initialized correctly. 编辑:如果我使用复制构造函数Polynomial p1(p2)声明多项式,p1将被正确初始化。 In the class FiniteFieldElement, I'm getting wrong Polynomial parameters. 在FiniteFieldElement类中,我得到了错误的多项式参数。 I'm completely stumped. 我完全难过了。

My understanding is that Polynomial's copy constructor will be called when p and irr are being passed. 我的理解是,当p和irr被传递时,将调用Polynomial的复制构造函数。

That only partially correct. 那只是部分正确。 A copy is possibly made since the Polinomials are passed by value (but copy elision could mean no copy is made at all), but inside FiniteFieldElement(int l, Polynomial p, Polynomial irr) , Polynomial 's copy assignment operator will be called, assuming this->p and this->irr are of type Polynomial . 由于Polinomials是按值传递的,因此可能会复制(但复制省略可能意味着根本没有复制),但在FiniteFieldElement(int l, Polynomial p, Polynomial irr) ,将调用Polynomial的复制赋值运算符,假设this->pthis->irrPolynomial类型。 So your class' fields are the result of an assignment, not a copy. 所以你的班级字段是作业的结果,而不是副本。

So you should be looking at the implementation of your copy assignment operator. 因此,您应该查看复制赋值运算符的实现。

Are you actually initializing the polynomial? 真的在初始化多项式吗? Doing new int[degree_ + 1]; new int[degree_ + 1]; will not construct an initialized array, its values are garbage. 不会构造一个初始化的数组,它的值是垃圾。

Edit : Unless there is another very good reason why you need a int* you are better off using a std::vector as your polynomial coefficients container. 编辑 :除非有另一个很好的理由为什么你需要一个int*你最好使用std::vector作为你的多项式系数容器。 It will simplify object construction, destruction and assignment. 它将简化对象构造,破坏和分配。

This works well (which means the problem is in the part of the code which you are not showing us: the class defintions and assignment operators) 这很好用(这意味着问题出在你没有向我们展示的代码部分:类定义和赋值运算符)

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

and the implementations: 和实施:

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

and

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

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

main is just: 主要是:

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

If it works on your machine see how it differs from your implementation, both in code and in behavior. 如果它适用于您的计算机,请在代码和行为中查看它与您的实现的不同之处。

Thanks to everyone it turns out the Eclipse CDT debugger was giving me wrong values. 感谢大家,事实证明Eclipse CDT调试器给了我错误的值。 The same breakpoint in Visual studio (or just printing the values [see modulo below]) gives me the correct answers. Visual Studio中的相同断点(或只是打印值[见下面的模数])给出了正确的答案。 Maybe I'm not using it correctly, but when you enter a watch expression in the debugger you expect to get the right value. 也许我没有正确使用它,但是当您在调试器中输入监视表达式时,您希望获得正确的值。

Eclipse CDT bug

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM