lang:cpp:heritage
Différences
Ci-dessous, les différences entre deux révisions de la page.
| Les deux révisions précédentesRévision précédenteProchaine révision | Révision précédente | ||
| lang:cpp:heritage [2020/01/16 15:38] – [overload] : ajout de "Héritage" root | lang:cpp:heritage [2020/03/10 23:07] (Version actuelle) – supprimée root | ||
|---|---|---|---|
| Ligne 1: | Ligne 1: | ||
| - | ====override==== | ||
| - | Une classe enfant redéfinit une méthode du parent. Cela peut se faire avec ou sans l' | ||
| - | <code cpp> | ||
| - | #include < | ||
| - | |||
| - | class A | ||
| - | { | ||
| - | | ||
| - | virtual void f() { std::cout << " | ||
| - | }; | ||
| - | |||
| - | class B : public A | ||
| - | { | ||
| - | | ||
| - | void f() { std::cout << " | ||
| - | }; | ||
| - | |||
| - | int main() | ||
| - | { | ||
| - | B b; | ||
| - | A *a = &b; | ||
| - | // Sans virtual, on affiche " | ||
| - | // Avec virtual, on affiche " | ||
| - | a->f(); | ||
| - | b.f(); | ||
| - | } | ||
| - | </ | ||
| - | |||
| - | ====overload==== | ||
| - | * Cas général | ||
| - | Deux méthodes ont le même nom mais avec des arguments de type différent. | ||
| - | |||
| - | <code cpp> | ||
| - | #include < | ||
| - | |||
| - | void f() { std::cout << " | ||
| - | void f(int) { std::cout << " | ||
| - | |||
| - | int main() | ||
| - | { | ||
| - | f(); | ||
| - | f(1); | ||
| - | } | ||
| - | </ | ||
| - | |||
| - | Attention, il n'est pas possible d' | ||
| - | |||
| - | <code cpp> | ||
| - | // Ambigu et interdit | ||
| - | void f() { std::cout << " | ||
| - | int f() { std::cout << " | ||
| - | </ | ||
| - | |||
| - | * Cas de deux méthodes ayant le même prototype. | ||
| - | <code cpp> | ||
| - | void fn(int i, int j); | ||
| - | void fn(int i, int ...); | ||
| - | </ | ||
| - | Dans le cas de l' | ||
| - | |||
| - | * Héritage | ||
| - | Le compilateur ne sait pas gérer la surcharge à travers l' | ||
| - | <code cpp> | ||
| - | #include < | ||
| - | #include < | ||
| - | |||
| - | struct BaseInt | ||
| - | { | ||
| - | void Func(int) { std::cout << " | ||
| - | void Func(double) { std::cout << " | ||
| - | }; | ||
| - | |||
| - | struct BaseString | ||
| - | { | ||
| - | void Func(std:: | ||
| - | }; | ||
| - | |||
| - | struct Derived : public BaseInt, public BaseString | ||
| - | { | ||
| - | }; | ||
| - | |||
| - | int main() | ||
| - | { | ||
| - | Derived d; | ||
| - | d.Func(10.); | ||
| - | } | ||
| - | </ | ||
| - | |||
| - | Cela donne le message d' | ||
| - | |||
| - | main.cpp: | ||
| - | |||
| - | Il est nécessaire d' | ||
| - | |||
| - | <code cpp> | ||
| - | struct Derived : public BaseInt, public BaseString | ||
| - | { | ||
| - | using BaseInt:: | ||
| - | using BaseString:: | ||
| - | }; | ||
| - | </ | ||
| - | ====Méthodes statiques dans une interface==== | ||
| - | Normalement, | ||
| - | |||
| - | [[http:// | ||
| - | |||
| - | L' | ||
| - | <code cpp> | ||
| - | template < typename T > | ||
| - | class StaticInterface | ||
| - | { | ||
| - | public: | ||
| - | StaticInterface() | ||
| - | { | ||
| - | int(*fooCheck)(int) | ||
| - | bool(*barCheck)(bool) = T::bar; | ||
| - | } | ||
| - | }; | ||
| - | </ | ||
| - | |||
| - | Une implémentation de la classe : | ||
| - | <code cpp> | ||
| - | class DerivedClass : public StaticInterface< | ||
| - | { | ||
| - | public: | ||
| - | static int foo(int | ||
| - | static bool bar(bool param){ return 20; } | ||
| - | }; | ||
| - | </ | ||
| - | |||
| - | ====Cast vers un parent d'un héritage multiple==== | ||
| - | {{ lang: | ||
| - | |||
| - | Depuis '' | ||
| - | |||
| - | Il ne faut surtout pas faire (ci-dessous). Sinon, les méthodes virtuelles (au minimum) appelleront n' | ||
| - | <code cpp> | ||
| - | Parent2* p = reinterpret_cast< | ||
| - | </ | ||
| - | |||
| - | Il faut faire (ci-dessous). Puis un '' | ||
| - | <code cpp> | ||
| - | Parent2* p = static_cast< | ||
| - | </ | ||
| - | |||
| - | ====reinterpret_cast sur une classe avec héritage==== | ||
| - | Un '' | ||
| - | |||
| - | Par contre, un '' | ||
| - | |||
| - | [[https:// | ||
| - | |||
| - | ====Définir une méthode purement virtuelle d'un parent par un autre parent==== | ||
| - | Il est important que '' | ||
| - | |||
| - | Si '' | ||
| - | |||
| - | <code cpp> | ||
| - | class Base { | ||
| - | public: | ||
| - | virtual void test() = 0; | ||
| - | }; | ||
| - | |||
| - | template < | ||
| - | class Mixin : virtual T { | ||
| - | public: | ||
| - | virtual void test() override { /*... do stuff ... */ } | ||
| - | }; | ||
| - | |||
| - | class Example : public virtual Base, public virtual Mixin< | ||
| - | /* definitions specific to the Example class _not_including_ | ||
| - | a definition of the test() method */ | ||
| - | }; | ||
| - | </ | ||
| - | |||
| - | {{ : | ||
| - | |||
| - | [[https:// | ||
| - | |||
| - | ====Forcer un template à hériter d'une classe==== | ||
| - | <code cpp> | ||
| - | template <class M> | ||
| - | class InterfaceVisitable { | ||
| - | static_assert(std:: | ||
| - | "M must be a descendant of XXXXXXXX" | ||
| - | }; | ||
| - | </ | ||
| - | |||
| - | ====Caster T< | ||
| - | C'est impossible. La notion d' | ||
| - | |||
| - | L' | ||
| - | |||
| - | <code cpp> | ||
| - | #include < | ||
| - | #include < | ||
| - | |||
| - | class A | ||
| - | { | ||
| - | | ||
| - | int a; | ||
| - | }; | ||
| - | |||
| - | class B : public A | ||
| - | { | ||
| - | | ||
| - | int b; | ||
| - | }; | ||
| - | |||
| - | template< | ||
| - | class C | ||
| - | { | ||
| - | | ||
| - | T t[2]; | ||
| - | }; | ||
| - | |||
| - | int main() | ||
| - | { | ||
| - | C<A> a; | ||
| - | C<B> b; | ||
| - | |||
| - | std::cout << (((size_t)(& | ||
| - | std::cout << (((size_t)(& | ||
| - | |||
| - | return 0; | ||
| - | } | ||
| - | </ | ||
| - | |||
| - | Rendu : | ||
| - | < | ||
| - | 4 | ||
| - | 8 | ||
| - | </ | ||
lang/cpp/heritage.1579185536.txt.gz · Dernière modification : de root
