2014-01-10 195 views
0

我正在用一些文件編寫一個程序,我們假設所有包含都沒問題。這裏是縮短的代碼。 ZZ.hpp:靜態初始化C++,未設置值

class ZZ 
{ 
    public: 
     ZZ(ZZ const & a) { mpz_init_set(data, a.data); } 
     ZZ(int a = 0) { mpz_init_set_si(data, a); } 
. 
. 
. 

ZZmodN.hpp:

template <unsigned ID> 
class ZZmodN 
{ 
    public: 
    ZZmodN() = default; 
    ZZmodN(ZZmodN const &) = default; 
    template <typename T> 
    ZZmodN(T const & a) : value(a) { value %= modulus; } 
. 
. 
.  
    private: 
    ZZ value; 
    static ZZ modulus; 
}; 
template <unsigned ID> 
ZZ ZZmodN<ID>::modulus(19); 
. 
. 
. 

Polynomial.h:

class Polynomial{ 
    public: 
    std::vector<ZZmodN<0> > co; 
    Polynomial(){}; 
    Polynomial(ZZmodN<0> a){ 
     co.push_back(a); 
    } 
. 
. 

終於Field.h:

#include "Polynomial.h" 
class Field{ 
    public: 
    static Polynomial f; 
    Polynomial poly; 
    Field(){} 
. 
. 
}; 
Polynomial Field::f = Polynomial(1); 

問題:我在收到浮點異常時我呼叫最後一個(*)行,因爲'%'=模數時'模數'= 0;叫做。爲什麼是0而不是19?我查了一下,並且調用了19的ZZ構造函數。 請幫忙。

+0

我想你可能會看到[靜態初始化順序失敗](http://www.parashift.com/c++-faq/static-init-order.html)。 –

回答

6

您遇到的問題是static initialization order fiasco。在你的情況下,鏈接器在初始化ZZmodN<0>::modulus之前決定初始化Field::f

+1

+1偉大的思想...... 8v) –

+0

同步對象更有趣(特別是如果它們是某些更高級別對象初始化的一部分):D – Paranaix

1

如果您使modulus功能(如以下代碼中所示),您的問題應該消失。 _m必須在modulus()可以返回之前初始化。

template <unsigned ID> 
class ZZmodN 
{ 
public: 
    ZZmodN() = default; 
    ZZmodN(ZZmodN const &) = default; 
    template <typename T> 
    ZZmodN(T const & a) : value(a) { value %= modulus(); } // changed 

// ... 

private: 
    ZZ value; 

    // static ZZ modulus; 

    static ZZ modulus() 
    { 
     static ZZ _m(19); 
     return _m; 
    } 
}; 

//template <unsigned ID> 
//ZZ ZZmodN<ID>::modulus(19);