#include #include <vector> // dumb class, to make this example works template <typename T> struct shared_ptr { shared_ptr(T val) : _val(val) { } T release() { return _val; } T _val; }; struct Val { Val(int i) : _i(i) {} int _i; }; template <typename T> class release_iterator : public __gnu_cxx::__normal_iterator<typename std::vector<T>::pointer, std::vector<T> > { typedef __gnu_cxx::__normal_iterator<typename std::vector<T>::pointer, std::vector<T> > super; public: release_iterator() : super() { } release_iterator(const typename super::iterator_type& __i) : super(__i) { } // real behavior ! // typename std::vector<T>::reference // operator*() const // { // return *super::_M_current; // } // Ugly :( Val* operator*() const { return super::_M_current->release(); } }; class MonTableau : public std::vector<shared_ptr<Val*> > { typedef std::vector<shared_ptr<Val*> > super; public: typedef release_iterator<shared_ptr<Val*> > iterator; public: iterator begin() { return iterator(this->_M_impl._M_start); } iterator end() { return iterator(this->_M_impl._M_finish); } }; int main() { MonTableau tab; tab.push_back(new Val(5)); tab.push_back(new Val(12)); MonTableau::iterator end = tab.end(); for (MonTableau::iterator it = tab.begin(); it != end; ++it) std::cout << (*it)->_i << std::endl; return 0; }
Ce qui signifie donc que c'est au développeur de s'arranger pour, s'il stock par exemple ses classes dans un tableau de classes "mère génériques", n'utiliser ces dernières que dans un contexte ou il connait déjà à quel type il a réellement affaire, pour avoir un gain de taille et de performance ?
devoir spécifier virtual
#include struct A { void coucou() { std::cout << "A" << std::endl;} }; struct B : public A { void coucou() { std::cout << "B" << std::endl;} }; struct C { virtual void coucou() { std::cout << "C" << std::endl;} }; struct D : public C { void coucou() { std::cout << "D" << std::endl;} }; void normal() { A a; B b; C c; D d; a.coucou(); // Affiche A b.coucou(); // Affiche B c.coucou(); // Affiche C d.coucou(); // Affiche D } void pointeur_normal() { A* a = new A; B* b = new B; C* c = new C; D* d = new D; a->coucou(); // Affiche A b->coucou(); // Affiche B c->coucou(); // Affiche C d->coucou(); // Affiche D } void heritage() { A* a = new B; C* c = new D; a->coucou(); // Affiche A, oupsss non prise en compte de la classe fille B c->coucou(); // Affiche D } int main() { normal(); pointeur_normal(); heritage(); std::cout << "Taille de A: " << sizeof (A) << std::endl // 1 << "Taille de B: " << sizeof (B) << std::endl // 1 << "Taille de C: " << sizeof (C) << std::endl // 4 << "Taille de D: " << sizeof (D) << std::endl; // 4 return 0; }
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre questionSi on hérite puis redéfinie une méthode, c'est bien parce qu'elle fait des trucs en plus qui doivent être fait, je vois pas trop de cas d'utilisation pour lesquels le fait de "caster" B en A fait que l'on veuille effectivement retrouver complètement le fonctionnement des méthodes de A... ?