Example 1:
Q.ConvertToOrange();
What is Q? Let's say Q is a pointer to an element in an array of classes of type Convertor. Depending on the inheritence used, significant memory allocation may be required when initially declaring the object, as all applicable parts of inherited classes need to be declared as well. Do this every time a function is called and you can bog things down rather quickly.
You seem to be confusing declaration with initialization. If your Q has a lifetime outside of the scope of the function this line of code is in, then you would've needed to do something like new Q(). This would be no different than if you malloc the struct-equivalent and run some additional code for whatever initialization you need to do to make Q usable. In both cases the work is done only once, not every time you call the member function. As for initializing the applicable parts of the inherited class--if you truly needed to use inheritance in the first place, then you would've had to do the same initialization work if you implement it using structs and function pointers anyway.
If your Q's lifetime can be confined to the scope of the function, so that you can stack-allocate Q in a language like C++, then this is no different from using struct. The constructor is there because you may need to initialize the values of certain members in order to use the object. That same initialization would've been needed if you use a struct. If you can leave the constructor with no code, then a decent compiler should easily be able to inline it to no code if given the information (eg. you define it inline in the header file).
Languages like C++ even allows your Q's lifetime to be "static", ie. essential available for the entire duration of the program's execution. Those are either stack-allocated or allocated at the static data section of your program's memory, and works similarly to the stack-allocated case.
Is ConvertToOrange() a method in class Convertor? Is it native or is it inherited from another class? Is it overloaded according to this context and instead pointing to a different function than the one in the class definition? After the indirection is applied, is the ConvertToOrange() method still in the picture at all?
It sounds like you don't realize that all this consideration you're mentioning are resolved 99-100% at compile time by the compiler, at least for the languages I'm thinking of.
When processing ConvertToOrange(), are the member elements of Convertor native to the actual object called or were they inherited from a different class? Are they able to be accessed by the Convertor class at the time the method was called?
You're referring to information hiding. This has nothing to do with run-time performance, it's just semantics enforced by the compiler to keep you from depending too much on the existing implementation of some class or interface. For the languages I know, none of these considerations required any runtime processing AFAIK, unless you're thinking of something like Reflection in Java, which is not the usual way you'd be accessing class members in the first place.
ConvertToOrange(&Q);
What is Q? Q is a pointer to something. For all intents and purposes, let's call it a struct of type Convertor. Structs, when declared, simply allocate the number of bytes required to store the struct in memory. Even in dynamic array situations, this can be done quick and painlessly using a single call to malloc().
But you're forgetting that depending on how you're using Q, you may need to set some of its member variables to some appropriate values before you start passing a pointer of it to functions like ConvertToOrange. So you're implementing the so-called "extra" processing yourself.
Since ConvertToOrange() is a function on its own, and one that accepts a pointer to Convertor as its argumnent, it is guaranteed to unambiguously represent a single process, which is defined in the body of the function itself.
This has nothing to do with performance, since again the compiler can figure out how to do the right thing at compile time. This works because with inheritance and virtual functions, the class data contains an array of function pointers representing the true destination addresses to call. The compiler simply emits code to index into the array and execute a CALL into the address given by the function pointer.
If there is no inheritance involved, then you wouldn't need to make the member function virtual in the first place, and the compiler can just call the member function directly. Depending on how often the call occurs, the overhead of the extra indexing from using a virtual function may be negligible.
The members of the Convertor struct are merely offset from the location of the struct itself in memory, and are always accessible.
Again, this has nothing to do with performance. The reason for restricting access to certain members is when they are not part of the interface your object wishes to expose, but instead are implementation details that are subject to change. If you have full control of the source code of the class, you can always elect to make everything public and named uniquely. Some languages also gives you a way to access a member hidden by the name of another member in a derived class (eg. casting).
[edit: and one more thing, since you referred to memory layout also. Class members are not stored that much differently than struct members. You may not be able to accurately "predict" their exact locations if you merely read the source code of how the class is declared (because of all the extra "hidden" memory for virtual function pointers, if you elect to use it, plus members inherited from base classes), but otherwise, if you account for the extra stuff (none of which is code, which is never stored with the class data if that's your mental picture), it's no different from a struct. Besides, C doesn't guarantee any alignment for individual struct members either (your compiler might, but that's compiler-specific. Some compilers even have switches or preprocessing directives for setting the alignment to use). In any event, it would not be good practice for portability if you have any need to know exactly how the compiler lays out the members of a struct or a class.]
For someone telling me to read the C spec, [...]
You have a funny way of saying "Don't waste your time reading my posts," but I kept reading anyway.
I don't know what you mean by this, but the fact is, during the last argument over C, your responses show it is
you in fact who fails to understand some of the finer points in the C spec, and I'm not sure you still quite grasped that. Your current foray into OOP shows you seem to have even less understanding of how OOP languages get compiled.
You're right that with the greater semantic complexity of OOP languages, you can more easily write code that have more overhead than you realize, but that's as much a lack of understanding of how the OOP features work. You told me you shouldn't blame C for the user's incompetence, so I'd say you shouldn't blame an OOP language for the user's failure to understand how its features work. In any event, if you're talking about micro-managing performance at the individual CPU instruction level, then you would've been arguing for using assembly language, not C.
And the final pointer about where the actual perf bottleneck is still holds.