En C++, vous pouvez étendre un paramétrée de classe de base avec différentes valeur du paramètre dans la classe enfant?

StackOverflow https://stackoverflow.com/questions/2009295

Question

Dans toutes les langues que je comprends, ce n'est pas possible, mais quelqu'un me disait que c'était possible en C++, mais j'ai du mal à y croire.Essentiellement, lorsque vous choisissez la classe que vous créez une classe unique dans la phase de compilation n'est-ce pas?

Permettez-moi de savoir si je suis pas claire à ma question.

Voici ma tentative avec des explications sur ce que je suis en train de faire ( attention à la classe L ):

//; g++ ModifingBaseClassParameter.cpp -o ModifingBaseClassParameter;ModifingBaseClassParameter

#include <iostream>

using namespace std;

template<typename T>
class Base
{
    public:
        Base() {}
        Base(T& t) : m_t(t) {}
        T& getMem() {return m_t;}
    private:
        T m_t;
};

template<typename T>
class F: Base<T>
{};

template<typename T>
class L: F<long>
{};

int main()
{
     Base<int> i;
     F<float> f;
     L<long> l;

     cout<<i.getMem()<<endl;
//     cout<<f.getMem()<<endl; // why doesn't this work
//     cout<<l.getMem()<<endl; // why doesn't this work
}

Donc, comme vous pouvez le voir (j'espère que ma syntaxe logique) de la classe L est d'essayer de redéfinir ses parents float paramètre d'être longue.Il a certainement ne semble pas que ce qui est légal, mais je vais être différents experts.

Était-ce utile?

La solution

Si vous voulez dire de se demander si vous pouvez le faire en C ++:

template <> 
class ParamClass<Type1> : public ParamClass<Type2> 
{
};

alors oui, il est possible.

Il est très souvent utilisé, par exemple pour définir des listes de modèles ou d'hériter des traits d'un autre type.

Autres conseils

Qu'est-ce que vous avez demandé ne peut pas être fait directement - mais vous pouvez venir assez proche en utilisant un paramètre de modèle par défaut:

template <typename T>
class Base { };

template <typename T = int>
class X : Base<T> {};

class Y : Base<float>

class Z : X<long> {};

Dans ce cas particulier, le paramètre de modèle par défaut n'ajoute pas grand-chose. Vous devez fournir une liste de paramètres de modèle pour instancier un modèle, même si les valeurs par défaut sont fournies pour tous les paramètres. En tant que tel, ayant une valeur par défaut que vous substituez dans une classe dérivée est généralement utile pour les paramètres deuxième et les suivants.

#include <iostream>
#include <typeinfo>

using namespace std;

template<typename T>
class Base
{
    public:
        Base() {}
        Base(T& t) : m_t(t) {}
        T& getMem() {return m_t;}
    private:
        T m_t;
};

template<typename T>
class F: public Base<T>
{};

template<typename T>
class L: public F<long>
{};

int main()
{
     Base<int> iNTEGER;
     F<float> fLOAT;
     L<long> lONG;

     int x;
     cout << typeid(iNTEGER.getMem()).name() << endl;
     cout << typeid(fLOAT.getMem()).name() <<endl; // this works now :)
     cout << typeid(lONG.getMem()).name() <<endl; // this works now :)
}

l'héritage est privé par défaut dans c ++, une fois rendu public ce stephenmm écrit devrait fonctionner à moins que vous vouliez demander autre chose?

Prenez-vous sur les modèles?

template<typename T>
class Base
{
    public:
        Base() {}
        Base(T& t) : m_t(t) {}
        T& getMem() {return m_t;}
    private:
        T m_t;
};

class X: Base<int>
{};

class Y: Base<float>
{};

Vous devriez essayer de le compiler:

$ g++ so-test1.c++ -o so-test1.c++ && ./so-test
so-test1.c++:21: error: expected template-name before ‘<’ token
so-test1.c++:21: error: expected `{' before ‘<’ token
so-test1.c++:21: error: expected unqualified-id before ‘<’ token
so-test1.c++: In function ‘int main(int, const char**)’:
so-test1.c++:27: error: aggregate ‘Z z’ has incomplete type and cannot be defined

X n'est pas un modèle de classe, de sorte qu'il n'a pas de sens d'essayer de l'instancier dans l'

class Z: X<long> {};

X n'a pas de paramètres de modèle de remplacement.Rappelez-vous que

Base<int>

n'est pas un modèle de classe soit;c'est une classe dans son propre droit, mais entièrement instancié à partir d'un modèle.Vous pouvez faire ceci:

....
template<typename T>
class X: Base<T> 
{};
...
class Z: X<long> 
{};

Mais ici, il n'y a pas de confusion sur remplacer les paramètres du modèle.

template<typename T>
class X: Base<int> 
{};
...
class Z: X<long>
{};

fonctionne aussi, mais ici, le paramètre de modèle en X est inutilisée, et rien n'est substituée.

HTH

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top