C ++ classes use polymorphism using virtual methods and a pointer to the base class. Suppose base class A, derivatives B, C - then I can use instead of virtual methods, a void type pointer followed by a ghost type? The essence of polymorphism will not change!?

Example:

void *ptrVoid; B b1; C c1; ptrVoid=(B*)&b1; ptrVoid=(C*)&c1; ((C*)ptrVoid)->... 

If it is possible to implement polymorphism for what then we need virtual methods!?

  • And if there is no information about types B and C at the call site? - Dith
  • And in general, use parametric polymorphism (in C ++ these are templates - alexlz

4 answers 4

And who said that this is polymorphism? This is some kind of obscenity. Moreover, there are no methods in c ++, not to mention virtual methods (standard, clause 9.4. The phrase "virtual method" is not found in the standard). The correct polymorphism is that the correct function will be called by the pointer to the base class, and you do not need to know which class the heir is behind the pointer.

 class A { public: virtual void f() = 0; } class B: A{ public: void f() {}; } class C: A{ public: void f() {}; } A * b = new B(); A * c = new C(); b->f(); // здесь будет вызываться метод класса B c->f(); // здесь будет вызываться метод класса C 

You say, m, I can make a ghost. But you will have to store information about the type of class somewhere. And everything turns into such a mess

 class A { public: void f(){ std::cout << "abstract virtual methot was called" << std::endl;} int type; A() {type = 1;} } class B: A{ public: void f() {}; B() {type = 2;} } class C: A{ public: void f() {}; C() {type = 3;} } void callF(A* x) { switch (x->type) { 1: x->f(); break; 2: (B*)x->f(); break; 3: (C*)x->f(); break; default: std::cout << "unknown type " << x->type << std::endl; } } A * b = new B(); A * c = new C(); callF(b); callF(c); // здесь будет вызываться метод класса C 

And this (unless I made mistakes) will work. Moreover, in principle, it happens in real code. But the compiler simply has more information about the situation in the code. For example, the Java compiler can do not switch , but the usual if , if it sees that there are only two options. Or even make an explicit call, if it is clear what to call.

Is it worth it to write code? If code is written in C, then yes (moreover, some C programmers almost always write code like this). This is done (in a slightly different form, really), when they write on Gtk.

Is it worth it to write in C ++ code? not. why do what the compiler does? Why make the sunset manually?

But if it seems that polymorphism needs to be done in its own way, then it may be necessary to choose another programming language?

upd

Why use polymorphic.

  • Example 1. Let there be a game (starcraft, Cossacks, and the like). The class "base unit" is created. All units are inherited from it. All created units are added to one large array (vector, list). When you need to draw, then just in a loop, we call the draw function on everyone and don’t think, and who is there. Each object already knows how to draw it.
  • Hi 2. Messenger type Miranda or qvip. There are a bunch of different services (ICQ, jabber, mail). Everyone has a contact sheet. The messenger itself does not know anything about services, it simply calls functions, and due to virtuality and polymorphism, correct functions are called. At the same time, if a new service was added, then you do not need to rewrite all the code so that it would be in the know.
  • Anyway, I don’t understand the highlight of polymorphism, but I can just create two objects and use them for health!? B b; C c; bf (); cf (); - rejie
  • you can. I allow :) - KoVadim
  • @KoVadim: +1 for the sunset manually :) - VladD
  • @KoVadim "But you have to store information about the type of the class somewhere." Not in order of arrival - but RTTI disappeared somewhere? typeid , type_info ... - alexlz
  • @alexlz: if I'm not mistaken, RTTI only works if there are virtual functions :-P - VladD

Yes, polymorphism can be managed without dispatch manually. No, in 2013, no one does this way *, because everyone is tired of reinventing the wheel, and it is better to force the compiler to do something where you may well be mistaken.

The meaning of polymorphism is precisely the fact that you do not need to do a cast and know the runtime type of the object with the potential to make a mistake. With polymorphism, you simply call the method, and work out what you need without your manual control.

If you have only two or three objects, you can do well with a couple of ifs, there are no problems.

But if you have thousands of objects that come from other parts of the program, you will have to either use virtual methods, or make a huge switch before each call, in which you check the type of the object.

Example: you have 10 different classes inherited from a common ancestor. An ancestor has a зафигачить(int сколькоРаз) method зафигачить(int сколькоРаз) . You need to trigger the object зафигачить(номерОбъекта) for all these objects. How to do it? Without polymorphism, your code will look like this:

 for (int i = 0; i < objectPointers.size(); i++) { Base* pBase = objectPointers[i]; switch (pbase->type) { case TYPE_CLASS1: { Class1* pClass1 = static_cast<Class1*>(pBase); pClass1->зафигачить(i); } break; case TYPE_CLASS2: { Class2* pClass2 = static_cast<Class2*>(pBase); pClass2->зафигачить(i); } break; // и т. д. } } 

With polymorphism, you can easily do this code:

 for (int i = 0; i < objectPointers.size(); i++) { objectPointers[i]->зафигачить(i); } 

Agree, easier to understand and support. :)


* except in rare cases when they actually write in C, not C ++

     #include <iostream> using namespace std; class A{ public: virtual int f() = 0; }; class B : public A{ public: int f(){ cout << "+" << endl; return 0; } }; class C : public A{ public: int f(){ cout << "-" << endl; return 0; } }; int main(){ B b; C c; // твой вариант void * p; p = (B*)&b; ((B*)p)->f(); // вариант с виртуальным наследованием выглядит как то логичней и тратится меньше процессорного времени на преобразование. A * a; a = &b; a->f(); return 0; } 

      For some reason, I remembered the question of the level "why do we need classes in PHP". The correct answer that suits the person who sets it is: “they don't need fuck anywhere”. Polymorphism as well. Everything can be done without it.

      But when the code grows to production, and the programmers will work on it, and the team (and not the knee-ups) then the question will disappear by itself :)

      • Well, classes in php are needed because it is fashionable and glamorous. But "the code will grow to production" - this is when HelloWorld will be a few hundred lines long? Or thousands? - alexlz