2013-05-11 99 views
1

不关注实际的代码,只是阅读问题。 我有一个功能,需要两个参数类型多项式:复制构造函数的问题

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中,我收到错误的Polynomial参数。我完全被难住了。

+5

如果'Polinomial'没有用户定义的析构函数你泄漏''polinomial' INT []' – Andrei 2013-05-11 17:11:11

+1

你是如何确定这些参数是未初始化的,只是出于兴趣? – razlebe 2013-05-11 17:40:37

+0

@Andrei是的,我知道。我只是想明确说明析构函数与这个错误无关。 – 2013-05-11 19:58:19

回答

0

感谢大家,事实证明Eclipse CDT调试器给了我错误的值。 Visual Studio中的相同断点(或者只是打印值[请参阅下面的模块])给了我正确的答案。也许我没有正确使用它,但是当你在调试器中输入一个监视表达式时,你希望得到正确的值。

Eclipse CDT bug

3

我的理解是,当p和irr被传递时,Polynomial的拷贝构造函数将被调用。

这只是部分正确。由于Polinomials已按值传递(但副本省略可能意味着完全没有副本),但在FiniteFieldElement(int l, Polynomial p, Polynomial irr)内,将调用Polynomial的复制分配操作员,假设this->pthis->irr的类型为Polynomial,因此可能会复制副本。所以你的班级领域是任务的结果,而不是副本。

所以,你应该看着你的拷贝赋值运算符的实现。

+0

我无法理解它。复制构造函数很好。那么他如何在有限域元素中获得未定义的值? – 2013-05-11 17:17:29

+0

@EAGER_STUDENT也许赋值运算符坏了? – juanchopanza 2013-05-11 17:19:32

+1

但是,当他作为参考传递时,它的工作原理....至少这是在问题中所说的......如果我将参数更改为参考参数,它工作正常。赋值运算符没有被破坏。 – Bill 2013-05-11 17:20:57

1

实际上初始化多项式? 否则new int[degree_ + 1];不会构建初始化阵列,其值是垃圾。

编辑:除非有就是为什么你需要一个int*另一个很好的理由你最好使用std::vector作为多项式系数容器。它将简化对象的构建,销毁和分配。

这种运作良好,(这意味着问题是,你没有向我们展示了部分代码:类defintions和赋值运算符)

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

如果它在您的机器上正常工作,请在代码和行为方面了解它与实现的不同之处。