2017-02-27 1 views
0

Un membre statique peut être déclaré const, mais il doit ensuite être initialisé dans la déclaration. Considérez le cas suivant d'un tableau statique à initialiser avec le code dans les boucles:Existe-t-il un moyen de créer une valeur de classe const statique qui est initialisée avec une boucle?

class A { 
private: 
    enum { SIZE = 360 }; 
    static double* vertices; 
public: 
    static void staticInit(); 
}; 

double* A::vertices = new double[SIZE]; 
void A::staticInit() { 
    double a = 0, b = 0; 
    for (int i = 0; i < SIZE; i++, a += .01, b += .02) 
    vertices[i] = sin(a) + c2 * sin(b); 
} 

Le code ci-dessus fonctionnerait. Mais si l'intention est de rendre les sommets constants, alors le déclarer const donnera une erreur de compilation sur la fonction staticInit.

Dans un C++ plus ancien, je déclarais le pointeur const, et le transformais en non-const juste dans cette fonction, mais aujourd'hui, les compilateurs ne le permettent pas car il est dangereux. Bien sûr, ne pas déclarer le pointeur const est encore moins dangereux.

Existe-t-il un moyen de s'en sortir?

Répondre

3

créer une fonction makeVertices qui renvoie un std::array, puis initialiser la valeur static en l'appelant:

constexpr std::size_t size = 360; 

std::array<double, size> makeVertices() 
{ 
    std::array<double, size> vertices; 
    double a = 0, b = 0; 

    for (int i = 0; i < size; i++, a += .01, b += .02) 
     vertices[i] = sin(a) + c2 * sin(b); 

    return vertices; 
} 

(. Les deux makeVertices et size pourrait être défini à l'intérieur A)

class A { 
private: 
    static std::array<double, size> vertices; 
}; 

std::array<double, size> A::vertices = makeVertices(); 

Notez également l'utilisation de constexpr au lieu de enum pour représenter le num constantes erical - c'est idiomatique C++ 11.

+1

Merci, oui encore de "vieux" réflexes C++ – Dov

2

Je ne vois pas pourquoi vous ne pourriez pas faire tout ce que vous aimez. Pour simplifier l'utilisation:

const T * const p = Init(); 

T * Init() 
{ 
    T * result = new T[n]; 
    for (std::size_t i = 0; i != n; ++i) 
     InitOne(result[i]); 
    return result; 
} 

Vous devriez pouvoir appliquer ce schéma à votre membre de classe statique.