2013-05-11 95 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; 
} 

如果它在您的機器上正常工作,請在代碼和行爲方面瞭解它與實現的不同之處。