Outils pour utilisateurs

Outils du site


lang:cpp:heritage

Ceci est une ancienne révision du document !


Méthodes statiques dans une interface

Normalement, c'est interdit mais apparemment, c'est possible en faisant du bricolage.

Source, Archive

L'interface :

template < typename T >
class StaticInterface
{
  public:
    StaticInterface()
    {
      int(*fooCheck)(int)   = T::foo;
      bool(*barCheck)(bool) = T::bar;
    }
};

Une implémentation de la classe :

class DerivedClass : public StaticInterface<DerivedClass>
{
  public:
    static int foo(int  param){ return 10; }
    static bool bar(bool param){ return 20; }
};

Cast vers un parent d'un héritage multiple

Depuis Parent1, caster this vers Parent2.

Il ne faut surtout pas faire (ci-dessous). Sinon, les méthodes virtuelles (au minimum) appelleront n'importe quoi. De toute façon d'une manière générale, reinterpret_cast ne s'utilise que vers la classe la plus basse dans l'héritage.

Parent2* p = reinterpret_cast<Parent2*>(this);

Il faut faire (ci-dessous). Puis un cast naturel se fera de Enfant vers Parent2.

Parent2* p = static_cast<Enfant*>(this);

reinterpret_cast sur une classe avec héritage

Un static_cast ou un dynamic_cast ne pose pas de problème dans le cas d'héritage multiple.

Par contre, un reinterpret_cast d'un void * doit toujours se faire sur la classe la plus basse (la plus enfant). Un void * ne possède aucune information du type de la classe et donc le compilateur ne sait pas comment s'en sortir. Par exemple avec les méthodes virtuelles, il ne peut pas savoir à quelle classe appartient la première méthode en tête de la vtable. Il y a les mêmes problèmes avec les attributs de la classe.

Source, Archive

Définir une méthode purement virtuelle d'un parent par un autre parent

How to override a function in another base class? Archive

Il est important que Base ne contienne que les méthodes virtuelles car les deux classes Mixin et Example vont en hériter.

Si Base::test n'est pas purement virtuelle, ça sera toujours la méthode de la classe Mixin qui sera appelée.

class Base {
public:
    virtual void test() = 0;
};
 
template <typename T>
class Mixin : virtual T {
public:
    virtual void test() override { /*... do stuff ... */ }
};
 
class Example : public virtual Base, public virtual Mixin<Base> {
    /* definitions specific to the Example class _not_including_
       a definition of the test() method */
};

Forcer un template à hériter d'une classe

template <class M>
class InterfaceVisitable {
  static_assert(std::is_base_of<XXXXXXXX, M>::value,
                "M must be a descendant of XXXXXXXX");
};

Caster T<Base>* t = new T<Derive>()

C'est impossible. La notion d'héritage ne marche que pour la classe, pas pour les arguments du template.

L'exemple ci-dessous ne marche pas. Caster l'un en l'autre poserait des problèmes pour l'accès à la variable a.

#include <cstddef>
#include <iostream>
 
class A
{
 public:
  int a;
};
 
class B : public A
{
 public:
  int b;
};
 
template<typename T>
class C
{
 public:
  T t[2];
};
 
int main()
{
  C<A> a;
  C<B> b;
 
  std::cout << (((size_t)(&a.t[1])) - ((size_t)(&a.t[0]))) << std::endl;
  std::cout << (((size_t)(&b.t[1])) - ((size_t)(&b.t[0]))) << std::endl;
 
  return 0;
}

Rendu :

4
8
lang/cpp/heritage.1536872893.txt.gz · Dernière modification : 2018/09/13 23:08 de root