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.

Static Interfaces in C++ Archive du 13/08/2019 le 19/12/2019

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.

multiple inheritance: unexpected result after cast from void * to 2nd base class Archive du 04/03/2010 le 19/12/2019

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

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 */
};

How to override a function in another base class? Archive du 22/10/2013 le 19/12/2019

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.1576761908.txt.gz · Dernière modification : 2019/12/19 14:25 de root