2011-09-26 3 views
3

J'ai une situation plutôt étrange où j'aimerais pouvoir définir certaines constantes qu'une sous-classe d'un ABC peut surcharger.Polymorphe static const constantes dans un ABC?

struct A { 
    static const int a = 20; 
    virtual int func() = 0; 
}; 
struct B : public A { 
    static const int a = 3; 
    int func() { return 5; } 
}; 
struct C : public A { 
    static const int a = 4; 
    int func() { return 3; } 
}; 

Malheureusement, si j'utilise A *aPtr = new B, aPtr->a retournera 20, au lieu de 3.

Une solution que je vois est fonction d'une ligne (le long des lignes de func dans l'exemple ci-dessus), mais la La syntaxe des constantes est un peu plus appropriée pour cette situation en particulier conceptuellement. Existe-t-il une manière syntaxiquement raisonnable de résoudre les constantes à utiliser lors de l'exécution, où le code appelant n'a pas besoin de savoir quoi que ce soit après la création de l'objet initial?

+0

duplication possible de [Remplacer les variables statiques lors du sous-classement] (http://stackoverflow.com/questions/594730/overriding-static-variables-when-subclassing) –

+1

Le raisonnement qui sous-tend cela est erroné: une constante est supposée être, eh bien, * constant *. Ce n'est pas toujours constant et parfois quelque chose d'autre. De même, les membres statiques sont des propriétés de classes, et non d'instances, ils ne jouent donc aucun rôle dans l'héritage, qui est un concept basé sur * instance *. –

Répondre

8

Les constantes, en particulier les constantes statiques, ne peuvent pas être remplacées comme vous le demandez. Vous devez utiliser une fonction virtuelle à la place:

struct A { 
    virtual int get_a() { return 20; } 
    int func() = 0; 
}; 

struct B : public A { 
    virtual int get_a() { return 3; } 
    int func() { return 5; } 
}; 

struct C : public A { 
    virtual int get_a() { return 4; } 
    int func() { return 3; } 
}; 

Une autre option serait d'utiliser un modèle pour la place constante:

template< const int a_value = 20 > 
struct A { 
    static const int a = a_value; 
    int func() = 0; 
}; 

struct B : public A<3> { 
    int func() { return 5; } 
}; 

struct C : public A<4> { 
    int func() { return 3; } 
}; 
+5

Pour la version modélisée il faut noter que les classes 'B' et' C' sont maintenant complètement indépendantes, puisqu'elles ont des classes de base différentes. –

1

Vous pouvez obtenir une réponse de l'exemple lui-même! :) Juste déclarer une méthode comme get_a() qui est virtual et remplacer la même chose.

struct A { 
    static const int a = 20; 
    virtual int get_a() const { return a; } // <--- for A 
}; 
struct B : public A { 
    static const int a = 3; 
    virtual int get_a() const { return a; } // <--- for B 
}; 
struct C : public A { 
    static const int a = 4; 
    virtual int get_a() const { return a; } // <--- for C 
}; 

Notez également que seule la méthode peut être surchargée en C++ et non les variables.

Questions connexes